<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>

<HEAD>
	<META NAME="GENERATOR" Content="Visual Page 1.0 for Windows">
	<META HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=iso-8859-1">
	<TITLE>CowBite Virtual Harware Spec</TITLE>
</HEAD>

<BODY BGCOLOR="#FFFFFF">

<H2 ALIGN="CENTER"><BR>
<BR>
CowBite Virtual Hardware Specifications</H2>
<P ALIGN="CENTER"><FONT SIZE="2">Unofficial documentation for the CowBite GBA emulator<BR>
by </FONT><A HREF="mailto:SorcererXIII@yahoo.com"><FONT SIZE="2">Tom Happ</FONT></A></P>

<P ALIGN="CENTER"><FONT SIZE="2">Thu Jul 18 23:25:19  2002<BR>
<BR>
The most recent version is kept at <BR>
</FONT><A HREF="http://www.cs.rit.edu/~tjh8300/CowBite/CowBiteSpec.htm"><FONT SIZE="2">http://www.cs.rit.edu/~tjh8300/CowBite/CowBiteSpec.htm</FONT></A><FONT
SIZE="2"> <BR>
and </FONT><A HREF="http://www.cs.rit.edu/~tjh8300/CowBite/CowBiteSpec.zip"><FONT SIZE="2">http://www.cs.rit.edu/~tjh8300/CowBite/CowBiteSpec.zip</FONT></A><FONT
SIZE="2">.</FONT>


<BLOCKQUOTE>
	<P ALIGN="CENTER">Available <BR>
	<A HREF="CowBiteSpecFrame.htm" target="_parent"><B>With Frames</B></A> and <A HREF="CowBiteSpec.htm" target="_parent"><B>Without
	Frames</B></A>

</BLOCKQUOTE>

<H2><A NAME="Table of Contents"></A>Table of Contents<BR>

<HR ALIGN="CENTER">
</H2>
<P>1. <A HREF="#Introduction">Introduction</A><BR>
2. <A HREF="#CPU">CPU</A><BR>
3. <A HREF="#Memory Map">Memory</A><BR>
4. <A HREF="#Graphics Hardware Overview">Graphics Hardware Overview</A><BR>
5. <A HREF="#Backgrounds">Backgrounds</A><BR>
6. <A HREF="#OAM (sprites)">OAM/Sprites</A><BR>
7. <A HREF="#Windowing">Windowing</A><BR>
8. <A HREF="#Hardware Interrupts">Hardware Interrupts</A><BR>
9. <A HREF="#BIOS (Software Interrupts)">BIOS</A><BR>
10. <A HREF="#Memory-Mapped Hardware Registers">Memory-Mapped Hardware Registers</A>

<UL>
	<LI><A HREF="#Graphics Hardware Registers">Graphics Hardware Registers</A>
	<LI><A HREF="#Banked registers">Background Registers</A>
	<LI><A HREF="#Background Rotation/Scaling Regi">Background Scaling/Rotation Registers</A>
	<LI><A HREF="#Windowing Registers">Windowing Registers</A>
	<LI><A HREF="#Effects Registers">Effects Registers</A>
	<LI><A HREF="#Sound Controls">Sound Registers</A>
	<LI><A HREF="#DMA Source Registers">DMA Registers</A>
	<LI><A HREF="#Timer registers">Timer Registers</A>
	<LI><A HREF="#Serial Communication Registers">Serial Communication Registers</A>
	<LI><A HREF="#Keypad input and control registe">Keyboard Registers</A>
	<LI><A HREF="#Interrupt Registers">Interrupt Registers</A>
</UL>

<P>11. <A HREF="#Miscellaneous">Miscellaneous/Weirdness</A><BR>
12. <A HREF="#Links">Links</A><BR>
13. <A HREF="#Thanks">Thanks</A>
<H2><BR>
1. <A NAME="Introduction"></A>Introduction<BR>

<HR ALIGN="CENTER">
</H2>
<P>This document began as a scratchpad of notes that I added onto &quot;Agent Q's GBA Spec&quot; as I came across
new information and ideas while building the CowBite emulator. Agent Q is no longer able to maintain that document.
Because there is so much additional information here, I thought it would be a shame to keep it to myself, and thus
I'm releasing it again as a CowBite technical reference document. Though it has the name of the CowBite emulator
on it, the information should still be more or less (and unofficially) valid on actual hardware.<BR>
<BR>
I've tried to organize this document in a way that will be easy to navigate to the section you are looking for.
I also try to update whenever I find that something is missing or erroneous. However, I can't catch everything
without your feedback. If you find an error, have information not listed in this doc (and there is lots of <I>that</I>),
or think that something could be improved upon, please <A HREF="mailto:SorcererXIII@yahoo.com">contact me</A>.
<BR>
<BR>
For the most part, this document is a reference and not a tutorial or instruction manual. I have done my best to
provide samples and hints wherever I can, but if you are looking for a step-by-step guide, you will probably find
it easier to begin with a tutorial like Dovoto's <A HREF="http://216.167.73.47/~dovoto/English/tutorial_5.html">Pern
Project</A>, or one of the other tutorials on <A HREF="http://www.gbadev.org">www.gbadev.org</A> or in the <A HREF="#Links">links</A>
section of this page. <BR>
<BR>
All of this information has been obtained legally by piecing together information from the ARM docs, gbadev.org,
the gbadev mailing list, public domain demos, and other information such as the debug info from various emulators.
My sincerest <A HREF="#Thanks">thanks</A> to all of those who have mailed me with info and corrections!<BR>
<BR>
Send me mail (<A HREF="mailto:SorcererXIII@yahoo.com">SorcererXIII@yahoo.com</A>) with your comments and especially
with info and corrections. <BR>
<BR>
Tom Happ <BR>
<BR>
Revision 3.5 - (Colorful Version) Begun May 18th 2002 (Though updates are continuous)<BR>
Revision 3.0 - (HTML Version) Begun December 19th 2001<BR>
Revision 2.1 - I decided to rename this 3.0, as it turned out to be a major overhaul <BR>
Revision 2.0 - Begun July 23, 2001 (by me)<BR>
Revision 1.0 - (by Agent Q) 08/02/2001 <BR>
<BR>
I keep the most recent doc update at <BR>
<A HREF="http://www.cs.rit.edu/~tjh8300/CowBite/CowBiteSpec.htm">http://www.cs.rit.edu/~tjh8300/CowBite/CowBiteSpec.htm</A>
<H2></H2>
<H3>The Basics</H3>
<P>From the programmer's perspective, the system is composed of the following:<BR>
<BR>
<A HREF="#CPU">CPU</A> - A 16.78 Mhz ARM7tdmi<BR>
<A HREF="#Memory Map">Memory</A> - 8 to 11 distinct areas of memory (depending on the Game Pak).<BR>
<A HREF="#Memory-Mapped Hardware Registers">IO</A> - Special hardware functions available to the programmer, primarily
pertaining to graphics, sound, DMA, timers, serial communication, key input, and interrupts.<BR>
<BR>
Programs run on the GBA are usually contained in a &quot;Game Pak&quot;. A &quot;Game Pak&quot; consists mainly
of <A HREF="#GAME PAK ROM">ROM</A> and possibly <A HREF="#CART RAM">Cart RAM</A> (in the form of SRAM, Flash ROM,
or EEPROM, used mainly for save game info). The ROM is where compiled code and data is stored. Unlike home computers,
workstations, or servers, there are no disks or other drives, so everything that might otherwise have been stored
as separate resource files must be compiled into the program ROM itself. Luckily there are tools to aid in this
process. <BR>
<BR>
The primary means a program accesses specialized hardware for graphics, sound, and other IO is through the <A HREF="#Memory-Mapped Hardware Registers">memory-mapped
IO</A>. Memory mapped IO is a means of communicating with hardware by writing to/reading from specific memory addresses
that are &quot;mapped&quot; to internal hardware functions. For example, you might write to address <A HREF="#REG_DISPCNT">0x4000000</A>
with the value &quot;0x0100&quot;, which tells the hardware &quot;enable background 0 and graphics mode 0&quot;.
A secondary means is through the <A HREF="#System ROM">BIOS</A>, which is embedded in the internal GBA system ROM.
Using <A HREF="#BIOS (Software Interrupts)">software interrupts</A> it is possible to access pre-programmed (and
hopefully optimized) routines lying in the the system ROM. These routines then access the hardware through the
memory-mapped IO.<BR>
<BR>
Other regions of memory that are directly mapped to the hardware are <A HREF="#Palette">Palette RAM</A> (which
is a table consisting of all the available colors), <A HREF="#VRAM">VRAM</A> (which performs a similar function
to the video RAM on a PC - and thensome), and <A HREF="#OAM">OAM</A> (which contains the attributes for hardware
accelerated sprites).
<H3><BR>
Programming for the GBA</H3>
<P>C, C++, and ARM/Thumb assembly are the most common languages used in GBA development, mainly because they are
fast and relatively low level (i.e. there is a large degree of correspondance between the structure of the language
and underlying instruction set of the architecture). Members of the <A HREF="http://www.gbadev.org">GBA development
community</A> have put together some development kits that greatly simplify the task of configuring a C/C++ compiler
for GBA development. Two that I know of are Devkit Advance and HAM.<BR>
<BR>
Most GBA programs are structured around the timing of the CPU and graphics hardware. The LCD has a refresh rate
of about 59.73 hz, with each refresh consisting of a <A HREF="#VDraw">vertical draw</A> period (when the GBA is
drawing the screen) followed by a <A HREF="#VBlank">vertical blank</A> period (when nothing is being drawn). The
vertical draw and vertical blank periods are further subdivided into <A HREF="#HDraw">horizontal draw and blank</A>
periods. Programs typically use the VBlank and possibly the HBlank periods to update VRAM or graphics hardware
registers in order to avoid unwanted visual artifacts, leaving the VDraw and HDraw periods to perform any software
processing that will not effect the display. Common methods of syncing to VBlank include polling <A HREF="#REG_STAT">REG_DISPSTAT</A>
or <A HREF="#REG_VCOUNT">REG_VCOUNT</A>, calling the VBlankIntrWait <A HREF="#BIOS (Software Interrupts)">BIOS</A>
function, or setting up an <A HREF="#Hardware Interrupts">interrupt</A>.<BR>
<BR>
For those wishing to learn how to write a program for the GBA, this is not really the right place. This document
is more like a reference that you can keep open in the background and quickly thumb through as questions arise.
However, I suggest the following resources as being invaluable to the beginner:<BR>
<BR>
<A HREF="http://www.gbadev.org">http://www.gbadev.org</A> - This is one of the main hubs for GBA development on
the web, containing numerous docs, tutorials, demos (many with source code), tools, and news.<BR>
<BR>
<A HREF="http://www.devrs.com/gba">http://www.devrs.com/gba</A> - This is Jeff Frohwein's GBA site. Jeff Frohwein
is something of a GBA dev guru; you will likely hear his name mentioned often throghout the community. His site
contains many good links, documents, and tools, many of which he wrote himself.<BR>
<BR>
<A HREF="http://groups.yahoo.com/group/gbadev/">http://groups.yahoo.com/group/gbadev/</A> -A forum on yahoo with
a large archive of back posts.<BR>
<BR>
<A HREF="http://216.167.73.47/~dovoto/English/tutorial_1.html">PERN project tutorials</A> - These great tutorials
by Dovoto explain everything in an easy-to-understand, step-by-step fashion.<BR>
<BR>
<A HREF="http://www.belogic.com/gba">The Audio Advance</A> - Documents and tutorials on the formerly enigmatic
GBA sound system. Courtesy of Uze.<BR>
<BR>
<A HREF="http://www.ngine.de/ham.html">HAM</A> - Emanuel's HAM devkit is especially easy to install and can have
you up and running in minutes.</P>
<PRE></PRE>
<H2><BR>
2. <A NAME="CPU"></A>CPU</H2>
<P>
<HR ALIGN="CENTER">
This section is intended to be an overview only, detailing those aspects of the CPU which are important to understand
when developing for the GBA in particular. A more thorough description of the ARM7tdmi CPU can be found in the
<A HREF="http://www.arm.com/arm/TRMs?OpenDocument">technical reference manuals</A> on <A HREF="http://www.arm.com">ARM's
website</A>.<BR>
<BR>
The CPU is a 16.78 MHz ARM7tdmi RISC processor. It is a 32-bit processor but can be switched to &quot;Thumb&quot;
state, which allows it to handle a special subset of 16-bit instructions that map to 32-bit counterparts. Instructions
follow a three-stage pipeline: fetch, decode, execute. As a result, the <A HREF="#r15 (PC)">program counter</A>
always points two instructions ahead of the one currently being executed.
<H3><BR>
<A NAME="CPU Registers"></A><B>CPU Registers</B></H3>
<P>16 registers are visible to the user at any given time, though there are 20 <A HREF="#Banked registers">banked
registers</A> which get swapped in whenever the CPU changes to various priveleged modes. The registers visible
in user mode are as follows:


<BLOCKQUOTE>
	<P><B>r0-r12:</B> General purpose registers, for use in every day operations<BR>
	<A NAME="r13 (SR)"></A><B>r13 (SR):</B> Stack pointer Register. Used primarily for maintaining the address of the
	stack. This default value (initialized by the BIOS) differs depending on the current <A HREF="#Processor Modes">processor
	mode</A>, as follows:
	<PRE>  User/System:  0x03007F00
  IRQ:          0x03007FA0
  Supervisor:   0x03007FE0</PRE>
	<P>As far as I know the other modes do not have default stack pointers.<BR>
	<BR>
	<A NAME="r14 (LR)"></A><B>r14 (LR):</B> Link Register. Used primarily to store the address following a &quot;bl&quot;
	(branch and link) instruction (as used in function calls)<BR>
	<A NAME="r15 (PC)"></A><B>r15 (PC):</B> The Program Counter. Because the ARM7tdmi uses a 3-stage pipeline, this
	register always contains an address which is 2 instructions ahead of the one currrently being executed. In 32-bit
	ARM state, it is 8 bytes ahead, while in 16-bit Thumb state it is 4 bytes ahead.<BR>
	<A NAME="CPSR"></A><B>CPSR:</B> The Current Program Status Register. This contains the status bits relevant to
	the CPU -</P>
	<PRE>31 30 29 28  27 26 25 24  23 22 21 20  19 18 17 16  15 14 13 12  11 10 9 8  7 6 5 4  3 2 1 0
<FONT COLOR="#008800">N </FONT> <FONT COLOR="#0099FF">Z </FONT> <FONT COLOR="#9900CC">C</FONT> <FONT COLOR="#FF0099"> V </FONT> <FONT
	COLOR="#FF3300"> R  R  R  R   R  R  R  R   R  R  R  R   R  R  R  R   R  R  R R </FONT><FONT COLOR="#008800"> I </FONT><FONT
	COLOR="#0099FF">F</FONT> <FONT COLOR="#9900CC">T</FONT> <FONT COLOR="#FF0099">M  M M M M</FONT></PRE>
	<PRE>0-4 <FONT COLOR="#FF0099"> (M)</FONT> = Mode bits. These indicate the current processor mode:
           10000 - <A HREF="#User">User mode
</A>           10001 - <A HREF="#FIQ">FIQ mode</A>
           10010 - <A HREF="#IRQ">IRQ mode
</A>           10011 - <A HREF="#SVC">Supervisor mode
</A>           10111 - <A HREF="#ABT">Abort mode
</A>           11011 - <A HREF="#UND">Undefined mode
</A>           11111 - <A HREF="#System">System mode</A></PRE>
	<PRE>5    <FONT COLOR="#9900CC">(T)</FONT> = <A HREF="#Thumb State">Thumb state</A> indicator. If set, the CPU is in Thumb state. 
           Otherwise it operates in normal ARM state. Software should
           never attempt to modify this bit itself.
6    <FONT COLOR="#0099FF">(F)</FONT> = FIQ interrupt disable. Set this to disable FIQ interrupts.
7 <FONT COLOR="#008800">   (I)</FONT> = <A HREF="#Hardware Interrupts">IRQ interrupt</A> disable. Set this to disable IRQ interrupts. On
           the GBA this is set by default whenever IRQ mode is entered.
           Why or how this is the case, I do not know.
8-27<FONT COLOR="#FF3300"> (R)</FONT> = Reserved
28 <FONT COLOR="#FF0099">  (V)</FONT> = Overflow condition code
29 <FONT COLOR="#9900CC">  (C)</FONT> = Carry/Borrow/Extend condition code
30 <FONT COLOR="#0099FF">  (Z)</FONT> = Zero/Equal condition code
31 <FONT COLOR="#008800">  (N)</FONT> = Negative/Less than condition code</PRE>

</BLOCKQUOTE>

<H3><A NAME="Processor Modes"></A><B>Processor Modes</B></H3>
<P>The ARM7tdmi has six modes: user, system, IRQ, FIQ, SVC, Undef, and Abt. The default is user mode. Certain events
will trigger a mode switch. Some modes cause an alternate set of registers to be swapped in, effectively replacing
the current set of registers until the mode is exited.<BR>
<BR>
<A NAME="User"></A><B>User: </B>This is the default mode.<BR>
<BR>
<A NAME="System"></A><B>System:</B> This is intended to be a priveleged user mode for the operating system. As
far as I can tell it is otherwise the same as User mode. I am not sure if the GBA ever enters System mode during
<A HREF="#BIOS (Software Interrupts)">BIOS</A> calls.<BR>
<BR>
<A NAME="IRQ"></A><B>IRQ:</B> This mode is entered when an Interrupt Request is triggered. Any interrupt handler
on the GBA will be called in IRQ mode.


<BLOCKQUOTE>
	<P><A NAME="Banked registers"></A>Banked registers: The ARM7tdmi has several sets of banked registers that get
	swapped in place of normal user mode registers when a priveleged mode is entered, to be swapped back out again
	once the mode is exited. In IRQ mode, r13_irq and r14_irq will be swapped in to replace r13 and r14. The current
	<A HREF="#CPSR">CPSR</A> contents gets saved in the SPSR_irq register.

</BLOCKQUOTE>

<P><A NAME="FIQ"></A><B>FIQ:</B> This mode is entered when a Fast Interrupt Request is triggered. Since all of
the hardware interrupts on the GBA generate IRQs, this mode goes unused by default, though it would be possible
to switch to this mode manually using the &quot;msr&quot; instruction.


<BLOCKQUOTE>
	<P>Banked registers: r8_fiq, r9_fiq, r10_fiq, r11_fiq, r12_fiq, r13_fiq, r14_fiq, and SPSR_fiq.

</BLOCKQUOTE>

<P><A NAME="SVC"></A><B>SVC:</B> Supervisor mode. Entered when a SWI (software interrupt) call is executed. The
GBA enters this state when calling the <A HREF="#BIOS (Software Interrupts)">BIOS</A> via SWI instructions.


<BLOCKQUOTE>
	<P>Banked registers: r13_svc, r14_svc, SPSR_svc.

</BLOCKQUOTE>

<P><A NAME="ABT"></A><B>ABT:</B> Abort mode. Entered after data or instruction prefetch abort.


<BLOCKQUOTE>
	<P>Banked registers: r13_abt, r14_abt, SPSR_abt.

</BLOCKQUOTE>

<P><A NAME="UND"></A><B>UND:</B> Undefined mode. Entered when an undefined instruction is executed.


<BLOCKQUOTE>
	<P>Banked registers: r13_und, r14_und, SPSR_und.

</BLOCKQUOTE>

<P>
<H3><A NAME="CPU State"></A>CPU State</H3>
<P>The ARM7tdmi has two possible states, either of which may be entered without fear of losing register contents
or current processor mode.<BR>
<BR>
<A NAME="Thumb State"></A><B>To enter Thumb State</B>: In this state the CPU executes 16-bit, halfword-aligned
instructions. There are two ways it can be entered:

<UL>
	<LI>A BX rn, where rn contains the address of the thumb instructions to be executed, +1. Bit 0 must be 1 or the
	switch won't be made and the CPU will try to interperet the binary Thumb code as 32-bit ARM instructions.
	<LI>Returning from an <A HREF="#Hardware Interrupts">interrupt</A> that was entered while in Thumb mode.
	<LI>Executing any arithmetic instruction with the PC as the target and the 'S' bit of the instruction set, with
	bit 0 of the new PC being 1.
</UL>

<P><A NAME="ARM State"></A><B>To Enter ARM State:</B> This is the default state. It executes 32-bit, word-aligned
instructions. When in Thumb state, the CPU can be switched back to ARM state by:

<UL>
	<LI>A BX rn, where rn contains the address of the ARM instructions to be executed. Bit 0 must be 0.
	<LI>Entering an <A HREF="#Hardware Interrupts">interrupt</A>.
</UL>

<P><B><BR>
For more complete information on the ARM7tdmi, be sure to check out ARM's </B><A HREF="http://www.arm.com/arm/TRMs?OpenDocument"><B>technical
reference manuals</B></A><B>.</B>
<H2><BR>
3. <A NAME="Memory Map"></A>Memory<BR>

<HR ALIGN="CENTER">
</H2>
<P>The following are the general areas of memory as seen by the CPU, and what they are used for. <BR>
<BR>
<A NAME="System ROM"></A><B>System ROM:</B></P>
<PRE>Start: 0x00000000
End:  0x0003FFF
Size: 16kb 
Port Size: 32 bit
Wait State: 0</PRE>
<P>0x0 - 0x00003FFF contain the <A HREF="#BIOS (Software Interrupts)">BIOS</A>, which is executable but not readable.
Any attempt to read in the area from 0x0 to 0x1FFFFFFF will result in failure; what you will see on a read is the
current prefetched instruction (the instruction after the instruction used to view the memory area), thus giving
the appearance that this area of memory consists of a repeating byte pattern. <BR>
<B><BR>
<A NAME="External Work RAM"></A>External Work RAM:</B></P>
<PRE>Start: 0x02000000
End:   0x0203FFFF
Size:  256kb
Port Size: 16 bit
Mirrors:  Every 0x40000 bytes from 0x02000000 to 0x02FFFFFF
</PRE>
<P>This space is available for your game's data and code. If a multiboot cable is present on startup, the BIOS
automatically detects it and downloads binary code from the cable and places it in this area, and execution begins
with the instruction at address 0x02000000 (the default is 0x08000000). Though this is the largest area of RAM
available on the GBA, memory transfers to and from EWRAM are 16 bits wide and thus consume more cycles than necessary
for 32 bit accesses. Thus it is advised that 32 bit ARM code be placed in <A HREF="#Internal Work RAM">IWRAM</A>
rather than EWRAM.<BR>
<B><BR>
<A NAME="Internal Work RAM"></A>Internal Work RAM:</B></P>
<PRE>Start: 0x03000000
End:   0x03007FFF
Size:  32kb
Port Size: 32 bit
Mirrors:  Every 0x8000 bytes from 0x03000000 to 0x03FFFFFF</PRE>
<P>This space is also available for use. It is the fastest of all the GBA's RAM, being internally embedded in the
ARM7 CPU chip package and having a 32 bit bus. As the bus for <A HREF="#GAME PAK ROM">ROM</A> and <A HREF="#External Work RAM">EWRAM</A>
is only 16 bits wide, the greatest efficiency will be gained by placing 32 bit ARM code in IWRAM while leaving
thumb code for <A HREF="#External Work RAM">EWRAM</A> or <A HREF="#GAME PAK ROM">ROM</A> memory.<BR>
<BR>
<A NAME="IO Ram"></A><B>IO Ram:</B></P>
<PRE>Start: 0x04000000
End:   0x040003FF (0x04010000)
Size:  1Kb
Port Size:  Dual ported 32 bit
Mirrors:  The word at 0x04000800 (only!) is mirrored every 0x10000 bytes
          from 0x04000000 - 0x04FFFFFF.
</PRE>
<P>This area contains a mirror of the ASIC (Application Specific Integrated Circuit) registers on the GBA. This
area of memory is used to control the graphics, sound, DMA, and other features. See <A HREF="#Memory-Mapped Hardware Registers">memory-mapped
IO registers</A> for details on the function of each register.<BR>
<BR>
<A NAME="Palette"></A><B>Palette RAM:</B></P>
<PRE>Start: 0x05000000
End:   0x050003FF
Size:  1kb
Port Size:  16 bit
Mirrors: Every 0x400 bytes from 0x05000000 to 0x5FFFFFF</PRE>
<P>This area specifies the <A HREF="#Color Format">16-bit color</A> values for the paletted modes. There are two
areas of the palette: one for backgrounds (0x05000000) and another for sprites (0x05000200). Each of these is either
indexed as a single, 256-color palette, or as 16 individual 16-color palettes, depending on the settings of a particular
<A HREF="#Attribute 0">sprite</A> or background. <BR>
<B><BR>
<A NAME="VRAM"></A>VRAM:</B></P>
<PRE>Start: 0x06000000
End:   0x06017FFF
Size:  96kb
Port Size: 16 bit
Mirrors: Bytes 0x06010000 - 0x06017FFF is mirrored from 0x06018000 - 0x0601FFFF.
         The entire region from 0x06000000 - 0x06020000 is in turn mirrored every
         0x20000 bytes from 0x06000000 - 0x06FFFFFF.</PRE>
<P>The video RAM is used to store the frame buffer in <A HREF="#Bitmapped Backgrounds">bitmapped</A> modes, and
the tile data and tile maps for tile-based <A HREF="#Text Backgrounds">&quot;text&quot;</A> and <A HREF="#Scale/Rotate Backgrounds">rotate/scale</A>
modes. <BR>
<B><BR>
<A NAME="OAM"></A>OAM:</B></P>
<PRE>Start: 0x07000000
End:   0x070003FF
Size:  1kb
Port Size: 32 bit
Mirrors: Every 0x400 bytes from 0x07000000 to 0x07FFFFFF</PRE>
<P>This is the Object Attribute Memory, and is used to control the GBA's <A HREF="#OAM (sprites)">sprites</A>.
<B><BR>
<BR>
<BR>
The following areas of memory are technically cart-dependent, but can generally be expected to behave as described.<BR>
<BR>
<A NAME="GAME PAK ROM"></A>GAME PAK ROM:</B></P>
<PRE>Start: 0x08000000
Size:  The size of the cartridge (0 - 32 megabytes) 
Port Size: 16 bit
<A HREF="#REG_WS_CR">Wait State</A>: 0</PRE>
<P>The ROM in the game cartridge appears in this area. If a cartridge is present on startup, the instruction found
at location 0x08000000 is loaded into the program counter and execution begins from there. Note that the transfers
to and from ROM are all 16 bits wide.<BR>
<B><BR>
GAME PAK <A NAME="ROM IMAGE 1"></A>ROM IMAGE 1:</B></P>
<PRE>Start: 0x0A000000
Size:  The size of the cartridge (0 - 32 megabytes)
Port Size:  16 bit
<A HREF="#REG_WS_CR">Wait State</A>: 1</PRE>
<P>This is a mirror of the ROM above. Used to allow multiple speed ROMs in a single game pak. <BR>
<B><BR>
GAME PAK <A NAME="ROM IMAGE 2"></A>ROM IMAGE 2:</B></P>
<PRE>Start: 0x0C000000
Size:  The size of the cartridge (0 - 32 megabytes)
Port Size: 16 bit
<A HREF="#REG_WS_CR">Wait State</A>: 2</PRE>
<P>This is a mirror of the ROM above. Used to allow multiple speed ROMs in a single game pak. <BR>
<B><BR>
<A NAME="CART RAM"></A>CART RAM:</B></P>
<PRE>Start: 0x0E000000 (also seem to appear at 0x0F000000)
Size:  0 - 64 kb
Port Size: 8 bit
</PRE>
<P>This is either SRAM or Flash ROM. Used primarily for saving game data. SRAM can be up to 64kb but is usually
32 kb. It has a battery backup so has the longest life (in terms of how many times it can be written to) of all
backup methods. Flash ROM is usually 64 kb. Its lifespan is determined by the number of rewrites that can be done
per sector (a 10,000 rewrite minimum is cited by some manufacturers).<BR>
<BR>
<A NAME="EEPROM"></A><B>EEPROM:</B><BR>
This is another kind of cart memory, but operates differently from SRAM or Flash ROM. Unfortunately, I don't know
the details of how it can be accessed by the programmer (<A HREF="SorcererXIII@yahoo.com">mail me</A> if you have
more information on it). It uses a serial connection to transmit data. The maximum size is 128 mb, but it can be
any size, and is usually 4 kb or 64 kb. Like Flash ROM it has a limited life; some manufacturers cite a minimum
of 100,000 rewrites per sector.<BR>
<BR>
There may be other regions of memory known as DEBUG ROM 1 and DEBUG ROM 2, though I really don't know whether these
are a part of commercial carts or if they are mapped to some part of the internal ROM, or if they're even available
on a standard GBA. <BR>
<BR>
Note that EWRAM, IWRAM, VRAM, OAM, Palette RAM are all initialized to zero by the BIOS (i.e. you can expect them
to be zeroed at startup).<BR>
<BR>
<BR>

<H2><BR>
4. <A NAME="Graphics Hardware Overview"></A>Graphics Hardware Overview<BR>

<HR ALIGN="CENTER">
</H2>
<P>The GBA has a TFT color LCD that is 240 x 160 pixels in size and has a refresh rate of exactly 280,896 cpu cycles
per frame, or around 59.73 hz. Most GBA programs will need to structure themselves around this refresh rate. Each
refresh consists of a 160 scanline vertical draw (<A NAME="VDraw"></A>VDraw) period followed by a 68 scanline blank
(<A NAME="VBlank"></A>VBlank) period. Furthermore, each of these scanlines consists of a 1004 cycle draw period
(<A NAME="HDraw"></A>HDraw) followed by a 228 cycle blank period (<A NAME="HBlank"></A>HBlank). During the HDraw
and VDraw periods the graphics hardware processes background and obj (sprite) data and draws it on the screen,
while the HBlank and VBlank periods are left open so that program code can modify background and obj data without
risk of creating graphical artifacts.
<H3><A NAME="Video Modes"></A>Video Modes</H3>
<P>Exactly what the GBA draws on screen depends largely on the current video mode (also sometimes referred to as
the <I>screen mode</I> or <I>graphics mode</I>). The GBA has 6 such modes, some of which are <A HREF="#Bitmapped Backgrounds">bitmap</A>-based
and some of which are <A HREF="#Text Backgrounds">tile-based</A>. The video mode is set by the bottom three bits
of the hardware register known as <A HREF="#REG_DISPCNT">REG_DISPCNT</A>. Background data is handled differently
depending on what mode is enabled. Backgrounds can either be <A HREF="#Text Backgrounds">text backgrounds</A> (tile
based), <A HREF="#Scale/Rotate Backgrounds">rotate-scale backgrounds</A> (tile based backgrounds that can be transformed),
or <A HREF="#Bitmapped Backgrounds">bitmap backgrounds</A>. The number of sprites available on screen is also dependent
on the mode; modes with tile-based backgrounds support 128 sprites, while modes with bitmapped backgrounds will
only support 64 sprites. <BR>
<BR>
Enabling objs and one or more backgrounds in <A HREF="#REG_DISPCNT">REG_DISPCNT</A> will cause the GBA to draw
the specified backgrounds and objs in order of priority. <BR>
<BR>
<A NAME="Mode 0"></A><B>Mode 0:<BR>
</B>In this mode, four text background layers can be shown. In this mode backgrounds 0 - 3 all count as <A HREF="#Text Backgrounds">&quot;text&quot;</A>
backgrounds, and cannot be scaled or rotated. Check out the section on <A HREF="#Text Backgrounds">text backgrounds</A>
for details on this. <BR>
<BR>
<A NAME="Mode 1"></A><B>Mode 1:</B><BR>
This mode is similar in most respects to Mode 0, the main difference being that only 3 backgrounds are accessible
-- 0, 1, and 2. Bgs 0 and 1 are <A HREF="#Text Backgrounds">text backgrounds</A>, while bg 2 is a <A HREF="#Scale/Rotate Backgrounds">rotation/scaling</A>
background.<BR>
<BR>
<A NAME="Mode 2"></A><B>Mode 2:</B><BR>
Like modes 0 and 1, this uses tiled backgrounds. It uses backgrounds 2 and 3, both of which are <A HREF="#Scale/Rotate Backgrounds">rotate/scale
backgrounds</A>. <BR>
<BR>
<A NAME="Mode 3"></A><B>Mode 3:</B> <BR>
Standard 16-bit bitmapped (non-paletted) 240x160 mode. The map starts at 0x06000000 and is 0x12C00 bytes long.
See the <A HREF="#Color Format">Color Format</A> table above for the format of these bytes. <BR>
<BR>
This allows the full color range to be displayed at once. Unfortunately, the frame buffer in this mode is too large
for page flipping to be possible. One option to get around this would be to copy a frame buffer from work RAM into
VRAM during the retrace, or (so I have heard) to use <A HREF="#REG_DMA3CNT">DMA3</A> with the start mode bits set
to 11.<BR>
<BR>
<A NAME="Mode 4"></A><B>Mode 4:</B><BR>
8-Bit paletted bitmapped mode at 240x160. The bitmap starts at either 0x06000000 or 0x0600A000, depending on bit
3 of <A HREF="#REG_DISPCNT">REG_DISPCNT</A>. Swapping the map and drawing in the one that isn't displayed allows
for page flipping techniques to be used. The palette is at 0x5000000, and contains 256 16-bit <A HREF="#Color Format">color
entries</A>. <BR>
<BR>
<A NAME="Mode 5"></A><B>Mode 5:</B><BR>
This is another 16-bit bitmapped mode, but at a smaller resolution of 160x128. The display starts at the upper
left hand corner of the screen, but can be shifted using the rotation and scaling registers for BG2. The advantage
of using this mode is presumably that there are two frame buffers available, and this can be used to perform page
flipping effects which cannot be done in mode 3 due to the smaller memory requirements of mode 5. Bit 3 of <A HREF="#REG_DISPCNT">REG_DISPCNT</A>
sets the start of the frame buffer to 0x06000000 when bit 3 is zero, and 0x600A000 when bit 3 is one.
<H3><A NAME="Color Format"></A><B>Color Format:</B></H3>
<P>All colors (both paletted and bitmapped) are represented as a 16 bit value, using 5 bits for red, green, and
blue, and ignoring bit 15. In the case of paletted memory, pixels in an image are represented as 8 bit or 4 bit
indices into the <A HREF="#Palette">palette RAM</A> starting at 0x5000000 for backgrounds and 0x50002000 for sprites.
Each palette is a table consisiting of 256 16-bit color entries. In the case of the bitmapped backgrounds in modes
3 and 4, pixels are represented as the 16-bit color values themselves.</P>
<PRE>F E D C  B A 9 8  7 6 5 4  3 2 1 0
<FONT COLOR="#BBBBBB">X</FONT> <FONT COLOR="#0000DD">B B B  B B</FONT> <FONT COLOR="#008800">G G  G G G</FONT> <FONT
COLOR="#DD0000">R  R R R R</FONT></PRE>
<PRE>0-4 <FONT COLOR="#DD0000">(R)</FONT> = Red
5-9 <FONT COLOR="#008800">(G)</FONT> = Green
A-F <FONT COLOR="#0000DD">(B)</FONT> = Blue</PRE>
<P>
<H2>5. <A NAME="Backgrounds"></A>Backgrounds</H2>
<P>Depending on the current <A HREF="#Video Modes">video mode</A>, three different types of backgrounds are available.
They are
<H3><A NAME="Text Backgrounds"></A>Text Backgrounds:</H3>
<P>These are tile-based backgrounds that descend from the usage of tiles to display characters in text modes of
a PC or workstation. They are made up of 8x8 tiles, the bitmaps of which are stored at the tile data address. The
address of this data is set using registers <A HREF="#REG_BG0">REG_BG0CNT - REG_BG3CNT</A>. The <A HREF="#REG_BG0SCX">HOFS</A>
and <A HREF="#REG_BG0SCY">VOFS</A> registers can be used to scroll around a larger area of up to 512x512 pixels
(or 64 x 64 tiles). <BR>
<BR>
In text backgrounds, the data for each pixel is stored as an 8 or 4 bit palette index. In 8-bit mode, the <A HREF="#Palette">palette</A>
is at 0x05000000 stores a 15-bit color value for each of the 256 palette entries. In 4-bit mode, the the map index
contains a 4-bit value indicating which of 16 16-color palettes to use for each tile. Each of these palettes is
32 bytes long and can be found at 0x05000000, 0x05000020, etc.
<H3><A NAME="Scale/Rotate Backgrounds"></A><B>Scale/Rotate Backgrounds</B>:</H3>
<P>These backgrounds are also tile-based, and operate similarly to Text Backgrounds. However, these backgrounds
may also be <A HREF="#Background Rotation/Scaling Regi">scaled or rotated</A>. Additionally they may only use an
8-bit <A HREF="#Palette">palette</A>, and can vary in size from 128 to 1024 pixels across. The palette is at 0x5000000,
and contains 256 16-bit <A HREF="#Color Format">color entries</A>
<H3><A NAME="Bitmapped Backgrounds"></A><B>Bitmapped Backgrounds</B>:</H3>
<P>These backgrounds vary depending on the <A HREF="#Video Modes">video mode</A>, but in all cases they rely on
a single buffer upon which the image is drawn, either using an 8-bit palette or 16-bit color entries themsevles.
Bitmap backgrounds are treated as BG2 for purposes of rotation, scaling, and blending. In the bitmap modes the
frame buffer data extends into the obj tile data region, limiting it to the range from 0x6014000 - 0x6018000 (sprite
indices 512 - 1024).
<H3><A NAME="Background Map Entry Format"></A><B>Background Map Entry Format</B></H3>
<P><A NAME="Text Background Map Format:"></A><A HREF="#Text Backgrounds"><B>Text Background</B></A><B> Map Format</B>:
<BR>
The tile map, which stores the layout of the tiles on screen, begins at the tile map address found for a particular
background, detrmined by <A HREF="#REG_BG0">REG_BG0CNT - REG_BG3CNT</A>. It has a selectable size up to 512x512.
The tile map contains a 16-bit entry for each tile, with has the following format:</P>
<PRE>F E D C  B A 9 8  7 6 5 4  3 2 1 0 
<FONT COLOR="#008800">L L L L</FONT>  <FONT COLOR="#0099FF">V</FONT> <FONT COLOR="#9900CC">H</FONT> <FONT COLOR="#FF0099">T T  T T T T  T T T T</FONT> </PRE>
<PRE>0-9 <FONT COLOR="#FF0099">(T)</FONT> = The tile number 
A <FONT COLOR="#9900CC">  (H)</FONT> = If this bit is set, the tile is flipped horizontally left to right. 
B <FONT COLOR="#0099FF">  (V)</FONT> = If this bit is set, the tile is flipped vertically upside down. 
C-F <FONT COLOR="#008800">(L)</FONT> = Palette number </PRE>
<P><BR>
For 256 x 256 and 256 x 512 backgrounds, the formula for calculating a map index is roughly,


<BLOCKQUOTE>
	<P>mapEntry = tileMapAddress[(tileY * 32) + tileX]

</BLOCKQUOTE>

<P>For text mode sizes 512 x 256 and 512 x 512 backgrounds, however, the map is 64 tiles across, and these are
stored in blocks of 32 * 32 tiles. This means that to calculate the map entry that would appear 33 tiles or more
across the background, the following equation should be used:


<BLOCKQUOTE>
	<P>mapEntry = tileMap[(tileY * 32) + (tileX - 32) + 32*32]

</BLOCKQUOTE>

<P>For entries 33 tiles or more down (in mode 11), use


<BLOCKQUOTE>
	<P>mapEntry = tileMap[( (tileY-32) * 32) + tileX + 2*32*32];

</BLOCKQUOTE>

<P>And for entries 33 tiles or more down and 33 tiles or more across,


<BLOCKQUOTE>
	<P>mapEntry = tileMap[( (tileY-32) * 32) + (tileX-32) + 3*32*32];

</BLOCKQUOTE>

<P><BR>
<A NAME="Rotational Background Map Format"></A><B>Rotational Background Map Format : </B><BR>
This is the same idea as the <A HREF="#Text Background Map Format:">text background</A> map format, but you only
have 8 bits for each entry. The format for the tile map entries is</P>
<PRE>7 6 5 4 3 2 1 0 
<FONT COLOR="#FF0099">T T T T T T T T</FONT> </PRE>
<PRE>0-7 <FONT COLOR="#FF0099">(T)</FONT> = The tile number </PRE>
<P><BR>
Rotational backgrounds do not divide tile maps into blocks.<BR>
<BR>

<HR ALIGN="CENTER">
<BR>
For specific details on the format of background data and map entries, check out the section on <A HREF="#REG_BG0">REG_BG0CNT
- REG_BG3CNT</A> (addresses 0x04000008 - 0x0400000E). <BR>
<BR>
In all modes up to 128 sprites can be displayed as well as the 4 background layers. These use the second <A HREF="#Palette">palette</A>
which is located at 0x05000200. See the <A HREF="#OAM (sprites)">OAM</A> section for details on how to display
sprites. <BR>
<BR>
Both background tiles and sprites use palette entry 0 as the transparent color. Pixels in this color will not be
drawn, and allow other background layers and sprites to show through.
<H2><BR>
6. <A NAME="OAM (sprites)"></A>OAM (sprites)</H2>
<P><BR>
The GBA supports 128 simultaneous sprites. These can be up to 64x64 pixels in size. The OAM, which starts at 0x07000000,
has one entry for each of the 128 sprites. Intermixed with this data are the rotation/scaling attributes, of which
there are 32 sets of 4 16 bit values. <BR>
<BR>
Each OAM entry is 8 bytes long and has the following format: <BR>
<BR>
<B>Bytes 1 and 2 (<A NAME="Attribute 0"></A>Attribute 0)</B></P>
<PRE>F E D C  B A 9 8  7 6 5 4  3 2 1 0
<FONT COLOR="#9900CC">S S</FONT> <FONT COLOR="#FF0099">A</FONT> <FONT COLOR="#FF3300">M</FONT>  <FONT COLOR="#008800">T T</FONT> <FONT
COLOR="#0099FF">D</FONT> <FONT COLOR="#9900CC">R</FONT> <FONT COLOR="#FF0099"> J J J J  J J J J</FONT>
</PRE>
<PRE>0-7 <FONT COLOR="#FF0099">(J)</FONT> = Y co-ordinate of the sprite (pixels). Note that for regular sprites,
          this is the y coordinate of the upper left corner. For rotate/scale
          sprites, this is the y coordinate of the sprite's center. center .
          Note on Coordinates: The values actually wrap around: to achieve a -1
          y coordinate, use y = 255.

8   <FONT COLOR="#9900CC">(R)</FONT> = Rotation/Scaling on/off 
9 <FONT COLOR="#0099FF">  (D)</FONT> = 0 - sprite is single sized;
          1 - sprite is virtually double sized; allowing sheared sprite pixels to
              overflow sprite the size (specified by bits 14 - 15 of
              <A HREF="#Attribute 1">OAM attribute 1</A>). A 16x16 sized sprite is treated internaly as a
              32x32 sprite. This specification comes in evidence when rotating a
              sprite at 45&deg;, since the H/V size of the sprite becomes 
              SQRT(16&sup2; + 16&sup2;) = SQRT(512) =~ 22.62 pixels. This will cause the
              sprite to appear clipped if this bit is set to 0. 
              (Thanks to Kay for the description)


A-B <FONT COLOR="#008800">(T)</FONT> = 00 - normal
          01 - semi-transparent
          10 - obj window
          11 - illegal code
          
          Note that semi-transparent sprites appear as transparent even if
          <A HREF="#REG_BLDCNT">REG_BLDMOD</A> has the sprites bit turned off.  Also note that
          sprites cannot be blended against one another.  For more details, see
          <A HREF="#REG_BLDCNT">REG_BLDMOD.</A>

C <FONT COLOR="#FF3300">  (M)</FONT> = enables mosaic for this sprite.
D <FONT COLOR="#FF0099">  (A)</FONT> = 256 color if on, 16 color if off 
E-F <FONT COLOR="#9900CC">(S)</FONT> = See below </PRE>
<P><BR>
<B>Bytes 3 and 4 (<A NAME="Attribute 1"></A>Attribute 1)</B></P>
<PRE>F E D C  B A 9 8  7 6 5 4  3 2 1 0
<FONT COLOR="#008800">S S</FONT><FONT COLOR="#0099FF"> V</FONT> <FONT COLOR="#9900CC">H</FONT>  <FONT COLOR="#BBBBBB">X X X</FONT> <FONT
COLOR="#FF0099">I  I I I I  I I I I</FONT>	(standard sprites)
<FONT COLOR="#008800">S S</FONT> <FONT COLOR="#FF3300">F F  F F F</FONT> <FONT COLOR="#FF0099">I  I I I I  I I I I </FONT> (rotation/scaling on)</PRE>
<PRE>0-8 <FONT COLOR="#FF0099">(I)</FONT> = X coordinate of the sprite (pixels). For regular sprites,
          this is the x coordinate of the upper left corner. For rotate/scale
          sprites, this is the x coordinate of the sprite's center. 
          Note on coordinates: The values actually wrap around. To achieve a 
          -1 x, use x = 511.

C <FONT COLOR="#9900CC">  (H)</FONT> = The flip horizinal bit
D <FONT COLOR="#0099FF">  (V)</FONT> = The flip vertical bit

9-D <FONT COLOR="#FF3300">(F)</FONT> = For rotation scaling sprites, the index into the rotation data to
          be used for that sprite. This index can be from 0 - 31. The
          rotation/scaling data is located in OAM <A HREF="#Attribute 3">attribute 3</A> (bytes 7 and 8).
          However, instead of the rotation and scaling data going with the
          corresponding sprite, it is separated accross four sequential sprites.
          This index can be thought of as referencing into an array of
          four-sprite blocks, 32 bytes each. 

E-F <FONT COLOR="#008800">(S)</FONT> = Size of the sprite. The top two bits of the size value are found in
          <A HREF="#Attribute 0">attribute 0</A> and the bottom two bits are in attribute 3. This forms a 
          4-bit value which sets the size of the sprite in the following way:

          <FONT COLOR="#9900CC">00</FONT><FONT COLOR="#008800">00</FONT>: 8  x 8         <FONT COLOR="#9900CC">10</FONT><FONT
COLOR="#008800">00</FONT>: 8  x 16
          <FONT COLOR="#9900CC">00</FONT><FONT COLOR="#008800">01</FONT>: 16 x 16        <FONT COLOR="#9900CC">10</FONT><FONT
COLOR="#008800">01</FONT>: 8  x 32
          <FONT COLOR="#9900CC">00</FONT><FONT COLOR="#008800">10</FONT>: 32 x 32        <FONT COLOR="#9900CC">10</FONT><FONT
COLOR="#008800">10</FONT>: 16 x 32
          <FONT COLOR="#9900CC">00</FONT><FONT COLOR="#008800">11</FONT>: 64 x 64        <FONT COLOR="#9900CC">10</FONT><FONT
COLOR="#008800">11</FONT>: 32 x 64
          <FONT COLOR="#9900CC">01</FONT><FONT COLOR="#008800">00</FONT>: 16 x 8         <FONT COLOR="#9900CC">11</FONT><FONT
COLOR="#008800">00</FONT>: Not used
          <FONT COLOR="#9900CC">01</FONT><FONT COLOR="#008800">01</FONT>: 32 x 8         <FONT COLOR="#9900CC">11</FONT><FONT
COLOR="#008800">01</FONT>: Not used
          <FONT COLOR="#9900CC">01</FONT><FONT COLOR="#008800">10</FONT>: 32 x 16        <FONT COLOR="#9900CC">11</FONT><FONT
COLOR="#008800">10</FONT>: Not used
         <FONT COLOR="#9900CC"> 01</FONT><FONT COLOR="#008800">11</FONT>: 64 x 32        <FONT COLOR="#9900CC">11</FONT><FONT
COLOR="#008800">11</FONT>: Not used</PRE>
<PRE></PRE>
<P><BR>
<B>Bytes 5 and 6 (<A NAME="Attribute 2"></A>Attribute 2)</B></P>
<PRE>F E D C  B A 9 8  7 6 5 4  3 2 1 0
<FONT COLOR="#0099FF">L L L L</FONT>  <FONT COLOR="#9900CC">P P</FONT> <FONT COLOR="#FF0099">T T  T T T T  T T T T</FONT></PRE>
<PRE>0-9 <FONT COLOR="#FF0099">(T)</FONT> = Tile number. This value indexes selects the bitmap of the tile to be
          displayed by indexing into the tile data area. Each index refernces
          32 bytes, so the memory address of a tile is roughly 0x6010000 + T*32.
          (see <A HREF="#Sprite Tile Data">Sprite Tile Data</A> for details) 

A-B <FONT COLOR="#9900CC">(P)</FONT> = <A HREF="#Priority">Priority</A>. This controls the priority of the sprite. Note thate sprites take
          precedence over backgrounds of the same priority.  See the <A HREF="#Priority">description of
</A>          <A HREF="#Priority">priority</A> under REG_BG0 - REG_BG3 for a more detailed explanation.

C-F <FONT COLOR="#0099FF">(L)</FONT> = Palette number. If you use 16 color <A HREF="#Palette">palettes</A>, this tells you which pallette
          number to use. </PRE>
<P><BR>
<B>Bytes 7 and 8 (<A NAME="Attribute 3"></A>Attribute 3)</B></P>
<PRE>F E D C  B A 9 8  7 6 5 4  3 2 1 0
<FONT COLOR="#0099FF">S</FONT> <FONT COLOR="#9900CC">I I I  I I I I</FONT>  <FONT COLOR="#FF0099">F F F F  F F F F</FONT></PRE>
<PRE>0-7 <FONT COLOR="#FF0099">(F)</FONT> = Fraction. 
8-E <FONT COLOR="#9900CC">(I)</FONT> = Integer
F = <FONT COLOR="#0099FF">(S)</FONT> = Sign bit</PRE>
<P><BR>
These bytes control sprite rotation and scaling. Instead of the rotation and scaling data going with the corresponding
sprite, it is separated accross four sequential sprites. This is indexed by bits 9 - 13 in <A HREF="#Attribute 1">attribute
1</A> (bytes 3 and 4). Note that these are all relative to the center of the sprite (background rotation/scaling
is relative to the upper left). Starting with sprite 0 and repeating every 4 sprites, they appear in the following
order:


<BLOCKQUOTE>
	<P><BR>
	<A NAME="Sprite 0, Attribute 3 - DX/PA"></A><B>Sprite 0, Attribute 3 - PA (DX):</B><BR>
	Scales the sprite in the x direction by an amount equal to 1/(register value). Thus, a value of 1.0 results in
	the original image size, while a value of 2 is half as large, and a value of .5 is twice as large.<BR>
	<BR>
	<A NAME="Sprite 1, Attribute 3 - DMX/PB"></A><B>Sprite 1, Attribute 3 - PB (DMX)</B>:<BR>
	Shears the x coordinates of the sprite over y. A value of 0 will result in no shearing, a value of 1.00 will make
	the image appear to be sheared left going down the screen, and a value of -1 will make the image appear sheared
	right going down the screen.<BR>
	<BR>
	<A NAME="Sprite 2, Attribute 3 - DY/PC"></A><B>Sprite 2, Attribute 3 - PC (DY)</B>:<BR>
	Shears the y coordinates of the sprite over x. A value of 0 will result in no shearing, a value of 1.00 will make
	the image appear to be sheared upwards to the right, and a value of -1 will make the image appear sheared downwards
	and to the right.<BR>
	<BR>
	<A NAME="Sprite 3, Attribute 3 - DMY/PD"></A><B>Sprite 3, Attribute 3 - PD (DMY)</B>:<BR>
	Scales the image in the y direction by an amount equal to 1/(register value). Thus, a value of 1.0 results in the
	original image size, while a value of 2 is half as large, and a value of .5 is twice as large.

</BLOCKQUOTE>

<P>
<H3><B>To Make a Sprite Rotate and Scale: (Taken from PERN Tutorial Day 3)</B></H3>
<P>The basic form of the equations for rotating and scaling is as follows:


<BLOCKQUOTE>
	<P>pa = x_scale * cos(angle);<BR>
	pb = y_scale * sin(angle);<BR>
	pc = x_scale * -sin(angle);<BR>
	pd = y_scale * cos(angle);

</BLOCKQUOTE>

<H3><BR>
<A NAME="Sprite Tile Data"></A><B>Sprite Tile Data</B></H3>
<P>The tile data area contains the actual bitmap for each tile. The sprites do not share tile data with the BG
layers as on the Gameboy Color. The sprite tile data starts at 0x06010000. All tiles are 8x8 pixels large. Sprites
use the second <A HREF="#Palette">palette</A> which begins at 0x05000200. For 256 color sprites, there are 64 bytes
per tile, one byte per pixel. This is an 8-bit value which is an index into the 256 color palette. For 16-color
sprites, <A HREF="#Attribute 2">attribute 2</A> (bytes 5 and 6) of the OAM data contains a 4 bit index into 16
16 color palettes, and sprites have 32 bytes per tile, with 4 bits per pixel. Note that the tile index references
32 bytes at a time, so in the case of 256 color sprite tiles, you will want to set your tile number to reference
ever other index (i.e. 0, 2, 4, 6, etc.). Another thing to note is that in the bitmapped modes (3-5) the memory
required to hold background data is larger than 0x10000 bytes, forcing the GBA to cut away from available sprite
tile data. Thus in these modes you may only reference sprites tiles of indices 512 and up.<BR>
<BR>
When the sprite is larger than 8x8 pixels, multiple tiles are glued together to make the sprite's width horizontally,
and then vertically. How this is done depends on whether character data is stored in 2d or 1d mode (determined
by bit 6 of <A HREF="#REG_DISPCNT">DISPCNT</A>).


<BLOCKQUOTE>
	<P><BR>
	<A NAME="1D Mapping"></A><B>1D Mapping:</B> <BR>
	In 1D mode, tiles are stored sequentially. If you were to set up a 32x32 16-color sprite, and set the tile number
	to 5, the sprite would be displayed as follows:</P>
	<PRE>---------------------
| 5  | 6  | 7  | 8  |
|    |    |    |    |
---------------------
| 9  | 10 | 11 | 12 |
|    |    |    |    |
---------------------
| 13 | 14 | 15 | 16 |
|    |    |    |    |
---------------------
| 17 | 18 | 19 | 20 |
|    |    |    |    |
---------------------</PRE>
	<P><BR>
	<A NAME="2D Mapping"></A><B>2D Mapping: </B><BR>
	Tiles on each row of the sprite are stored 32 slots in. Using the same 32x32 sprite above, with a tile number of
	5, the sprite would be displayed as:</P>
	<PRE>---------------------
| 5  | 6  | 7  | 8  |
|    |    |    |    |
---------------------
| 37 | 38 | 39 | 40 |
|    |    |    |    |
---------------------
| 69 | 70 | 71 | 72 |
|    |    |    |    |
---------------------
| 101| 102| 103| 104|
|    |    |    |    |
---------------------</PRE>

</BLOCKQUOTE>

<P>
<H2>7. <A NAME="Windowing"></A>Windowing<BR>

<HR ALIGN="CENTER">
</H2>
<P>Windowing is a method of dividing the screen into subsections known as (surprise) windows. The windows serve
as boundary areas to determine where various layers of the GBA will be shown and where they will be clipped. There
are two primary windows, win0 and win1, which can be enabled in <A HREF="#REG_DISPCNT">REG_DISPCNT</A>. There is
also the &quot;obj&quot; window, which can be thought of as another window which is defined by the visible regions
of the objs on screen. Finally there is the &quot;outside&quot; or &quot;out&quot; window - the area of the screen
not already occupied by any other winodw. The position and size of WIN0 and WIN1 are determined by <A HREF="#REG_WIN0_H">REG_WIN0H</A>,
<A HREF="#REG_WIN1_H">REG_WIN1H</A>, <A HREF="#REG_WIN0_V">REG_WIN0V</A>, and <A HREF="#REG_WIN1_V">REG_WIN1V</A>
(I/O offsets 0x40, 0x42, 0x44, 0x46). Exactly which characters and backgrounds appear within or without win0, win1,
and the obj window is determined by <A HREF="#REG_WIN_IN">REG_WININ</A> and <A HREF="#REG_WIN_OUT">REG_WINOUT</A>
(0x48 and 0x4A). <BR>
<BR>
Here are some things to keep in mind when using windows :


<BLOCKQUOTE>
	<P>- WIN0 and WIN1 are drawn from the left and top boundary up to but not including the right and bottom boundaries.<BR>
	- Everything in WIN0 appears &quot;above&quot; WIN1 (i.e. it has higher priority), and everything in windows 0
	&amp; 1 appears above the WINOUT and obj windows.<BR>
	- If a bg or the obj's are turned off in dispcnt, they're off in all windows regardless of the settings in win_in
	and win_out.<BR>
	- If only one window is on, WINOUT affects everything outside of it (if both windows are on, WINOUT affects everything
	outside both of them. IE, it affects (!WIN0)&amp;&amp;(!WIN1) ).<BR>
	- If a window is on, but the effective display bits are all clear, the backdrop is displayed.<BR>
	- If the window left coordinate is greater than the window right coordinate, the window will be drawn outside of
	this region (i.e. to the left and to the right) rather than in the area inbetween.<BR>
	- Likewise, if the window top coordinate is greater than the window bottom coordinate, the window will be drawn
	to the top and the bottom.<BR>
	- A completely inverted window is drawn in the area outside of the &quot;+&quot; shaped region defined by its boundaries.

</BLOCKQUOTE>

<P>Windows can be used in console games for a variety of different effects. Though the window registers define
a square region, differently shaped windows can be achieved by using <A HREF="#REG_DMA0CNT">hdma</A> or <A HREF="#Hardware Interrupts">hblank
interrupts</A> to change the parameters each scanline. Lantern lighting (when the hero has a lantern or flashlight
that illuminates a certain region of a cave) and x-ray vision (use of the window to cut away layers that are in
front) are two common effects created with windows. More are certainly possible.<BR>
<BR>
Thanks again to gbcft for most of these notes and for his extensive testing on the nature of windowing.
<H2><BR>
8. <A NAME="Hardware Interrupts"></A>Hardware Interrupts<BR>

<HR ALIGN="CENTER">
</H2>
<P>Figuring out hardware interrupts was kind of painful. Everything below is what I have gleaned from reading <A
HREF="http://www.arm.com">ARM's docs</A>, the list, the advice of other emulator and demo authors, and from various
other emulator's debug info. I hope it is of some use to you. Let me know if you find any errors or typos.<BR>
<BR>
<B>Key points: </B><BR>
- All hardware interrupt vectors lie in the BIOS. You cannot handle interrupts directly, you must go through the
BIOS. Thus, the instructions for exception handling in the ARM docs do not apply directly since we cannot handle
the exceptions directly. <BR>
<BR>
- Interrupts are enabled by setting the flags in the <A HREF="#REG_IE">REG_IE</A> and hardware registers like <A
HREF="#REG_STAT">REG_DISPSTAT</A>, <A HREF="#REG_KEYCNT">REG_KEYCNT</A>, and <A HREF="#DMA Control Registers">REG_DMAXCNT</A>.
The flag must be set in both REG_IE and the corresponding hardware register for it to work. When the interrupt
signal is sent, the appropriate flag is set in <A HREF="#REG_IF">REG_IF</A>. The program code unsets this flag
(by writing a 1 to that bit) in order to keep track of what interrupts have been handled. <BR>
<BR>
<B>- When an interrupt occurs, the CPU does the following:</B>


<BLOCKQUOTE>
	<P>1. Switches state to IRQ mode, bank-swaps the current stack register and link register (thus preserving their
	old values), saves the CPSR in SPSR_irq, and sets bit 7 (interrupt disable) in the CPSR. <BR>
	2. Saves the address of the next instruction in LR_irq compensating for Thumb/ARM depending on the mode you are
	in. <BR>
	3. Switches to <A HREF="#ARM State">ARM state</A>, executes code in BIOS at a hardware interrupt vector (which
	you, the programmer, never see)

</BLOCKQUOTE>

<P><B>- The BIOS code picks up at the hardware interrupt vector and does the following:</B>


<BLOCKQUOTE>
	<P>4. Pushes registers 0 - 3, 12, LR_irq (which cointains the address following the instruction when the interrupt
	occrued) onto the stack <BR>
	5. Places the address for the next instruction (in the BIOS, not in your code) in LR <BR>
	6. Loads the address found at 0x03007FFC <BR>
	7. Branches to that address.

</BLOCKQUOTE>

<P><B>- The program code at that address is executed.</B>


<BLOCKQUOTE>
	<P>8. It is the responsiblity of the code at that address to return once finished, <BR>
	using BX LR_irq

</BLOCKQUOTE>

<P><B>- The BIOS finishes up where your code leaves off:</B>


<BLOCKQUOTE>
	<P>9. It restores registers 0 - 3, 12, LR_irq <BR>
	10. Branches to the intruction found in LR, using a SUBS PC, LR_irq, #4

</BLOCKQUOTE>

<P><B>- Upon receiving the SUBS PC, LR_irq, #4 instruction, the CPU</B>


<BLOCKQUOTE>
	<P>11. Copies the SPSR_irq back into the CPSR, restoring the status bits to their <BR>
	state when the interrupt occurred, and bank swaps back in the stack register <BR>
	and link register. The CPU will thus be placed in the correct state (<A HREF="#ARM State">ARM</A> or <A HREF="#Thumb State">Thumb</A>)
	<BR>
	it was in when the exception occurred.

</BLOCKQUOTE>

<P><BR>
So, the basic model for setting up interrupts is: <BR>
<BR>
1. Place the address for your interrupt code at 0x03007FFC. <BR>
<BR>
2. Turn on the interrupts you wish to use:<BR>
- <A HREF="#REG_STAT">REG_DISPSTAT</A>, <A HREF="#REG_TM0CNT">REG_TMXCNT</A>, <A HREF="#REG_KEYCNT">REG_KEYCNT</A>,
or <A HREF="#REG_DMA0CNT">REG_DMAXCNT</A> tell the hardware which interrupts to send<BR>
- 0x04000200 (<A HREF="#REG_IE">REG_IE</A>) masks which interrupts will actually be serviced (?) <BR>
- 0x04000208 (<A HREF="#REG_IME">REG_IME</A>) Turns all interrupts on or off. <BR>
<BR>
3. When the interrupt is reached, the code at the address at 0x3007FFC gets loaded into the CPU. To prevent unwanted
errors/behavior, the first thing this code should do is disable interrupts.<BR>
<BR>
4. To determine what interrupt this is, check the flags in 0x04000202 (<A HREF="#REG_IF">REG_IF</A>). Unset the
flag by writing a 1 to that bit.<BR>
<BR>
5. Once finished with the service routine, reenable interrupts and execute a BX LR (*Not* a SUBS PC, LR #4, which
is what the BIOS does). The BIOS will then take over and return your program to where execution left off.
<H3><BR>
<A NAME="Types of Hardware Interrupts"></A>Types of Hardware Interrupts</H3>
<P>Enable these interrupts using <A HREF="#REG_STAT">REG_DISPSTAT</A>, <A HREF="#REG_TM0CNT">REG_TMXCNT</A>, <A
HREF="#REG_KEYCNT">REG_KEYCNT</A>, or <A HREF="#REG_DMA0CNT">REG_DMAXCNT</A>, then setting the correct flags in
<A HREF="#REG_IE">REG_IE</A> and <A HREF="#REG_IME">REG_IME</A>.<BR>
<BR>
V-Blank: Occurs when the <A HREF="#REG_VCOUNT">vcount</A> reaches 160, or 0xA0. (Enable in <A HREF="#REG_STAT">REG_DISPSTAT</A>)<BR>
<BR>
H-Blank: Occurs at the end of every raster line, from 0 - 228. H-blank interrupts DO occur during v-blank (unlike
hdma, which does not), so write your code accordingly. Thanks to gbcft for verifying this. (Enable in <A HREF="#REG_STAT">REG_DISPSTAT</A>)
<BR>
<BR>
Serial: I am unsure about this; I presume it has to do with the link cable. <BR>
<BR>
V-Count: Occurs when the <A HREF="#REG_VCOUNT">vcount</A> reaches the number specified in <A HREF="#REG_STAT">REG_DISPSTAT</A>.
<BR>
<BR>
Timer: These occur whenever one of the <A HREF="#Timer registers">timer registers</A> is set to cause an interrupt
whenever it overflows. Enable in <A HREF="#REG_TM0CNT">REG_TMXCNT</A>.<BR>
<BR>
DMA: These occur after a DMA transfer, according to the flags in the <A HREF="#DMA Control Registers">DMA_CNT</A>
registers and in <A HREF="#REG_IE">REG_IE</A>. Enable in <A HREF="#REG_DMA0CNT">REG_DMAXCNT</A>.<BR>
<BR>
Key: Occurs when the user presses or releases the buttons specified in <A HREF="#REG_KEYCNT">REG_KEYCNT</A>.<BR>
<BR>
Cassette: Occurs when the user yanks out or inserts the cartridge out while the GBA is still running. For a cartridge
interrupt to work properly the ISR must reside in RAM. It is possible to switch cartridges and have the routine
resume execution on a completely different ROM.
<H2><BR>
9. <A NAME="BIOS (Software Interrupts)"></A>BIOS (Software Interrupts - partially implemented in CowBite)<BR>

<HR ALIGN="CENTER">
</H2>
<P>The BIOS calls are basically SWI instructions; the value passed into the instruction tells the CPU which interrupt
to execute. There is very little public domain information on the BIOS. Marat Fayzullin has a listing of the BIOS
calls on his VGBA website, and Forgotten has added a list to his <A HREF="http://vboy.emuhq.com/faq.shtml">Visual
Boy Advance FAQ</A>.  It is using these, in combination with observing the behavior of various demos in CowBite
and other emulators that I was able to piece together what I have here.<BR>
<BR>
0x00: SoftReset 


<BLOCKQUOTE>
	<P>Resets the GBA and runs the code at address 0x2000000 or 0x8000000 depending on the contents of 0x3007ffa (0
	means 0x8000000 and anything else means 0x2000000).

</BLOCKQUOTE>

<P>0x01: RegisterRamReset 


<BLOCKQUOTE>
	<P>Performs a selective reset of memory and I/O registers.<BR>
	Input: r0 = reset flags

</BLOCKQUOTE>

<P>0x02: Halt 


<BLOCKQUOTE>
	<P>Halts CPU execution until an interrupt occurs.

</BLOCKQUOTE>

<P>0x03: Stop 


<BLOCKQUOTE>
	<P>Stops the CPU and LCD until the enabled interrupt (keypad, cartridge or serial) occurs.

</BLOCKQUOTE>

<P>0x04: IntrWait 


<BLOCKQUOTE>
	<P>Waits for the given interrupt to happen.<BR>
	Input: r0 = initial flag clear, r1 = interrupt to wait

</BLOCKQUOTE>

<P>0x05: VBlankIntrWait


<BLOCKQUOTE>
	<P>--Waits for vblank to occur. Waits based on interrupt rather than polling in order to save battery power.<BR>
	Equivalent of calling IntrWait with r0=1 and r1=1.

</BLOCKQUOTE>

<P>0x06: Div


<BLOCKQUOTE>
	<P>Input: r0 = numerator, r1 = denominator <BR>
	Output: r0 = numerator/denominator <BR>
	r1 = numerator % denominator; <BR>
	r3 = abs (numerator/denominator)

</BLOCKQUOTE>

<P>0x07: DivArm 


<BLOCKQUOTE>
	<P>Input: r0 = denominator, r1 = numerator<BR>
	Output: r0 = numerator/denominator <BR>
	r1 = numerator % denominator; <BR>
	r3 = abs (numerator/denominator)

</BLOCKQUOTE>

<P>0x08: Sqrt


<BLOCKQUOTE>
	<P>Input: r0 = number <BR>
	Output: r0 = sqrt(number)

</BLOCKQUOTE>

<P>0x09: ArcTan


<BLOCKQUOTE>
	<P>Input: r0 = angle (signed 16-bit)<BR>
	Output: r0 = arctan(angle);

</BLOCKQUOTE>

<P>0x0A: ArcTan2 


<BLOCKQUOTE>
	<P>Calculates the arctangent of the given point.<BR>
	Input: r0 = X (signed 16-bit), r1 = Y (signed 16-bit)<BR>
	Output: r0=arctan

</BLOCKQUOTE>

<P><BR>
0x0B: CPUSet


<BLOCKQUOTE>
	<P>- Performs a memory transfer.<BR>
	Input: r0 = source address, r1 = dest address <BR>
	r2 (guess) - formatted like DMA transfer <BR>
	bit26 = 32 or 16 bit transfer <BR>
	bits 15 - 0 = number of transfers

</BLOCKQUOTE>

<P>0x0C: CPUFastSet


<BLOCKQUOTE>
	<P>- Also performs a memory transfer, in 32-bit blocks, presumably with some optimization (and limitations?). I
	believe the register parameters are set up the same as, or at least similar to, those for CPUSet.

</BLOCKQUOTE>

<P>0x0D: BiosChecksum


<BLOCKQUOTE>
	<P>Calculates the checksum of the whole BIOS by adding every 32-bit word from the BIOS.<BR>
	Output: r0 = BIOS checksum<BR>
	Note: this seems to only be present in the release version of the BIOS

</BLOCKQUOTE>

<P>0x0E: BgAffineSet 


<BLOCKQUOTE>
	<P>Calculates the affine parameters for sprites (rotation and scaling).<BR>
	Input: r0 = source, r1 = dest, r2 = number of calculations, r3 = offset between calculations

</BLOCKQUOTE>

<P><BR>
0x0F: ObjAffineSet <BR>
0x10: BitUnPack 


<BLOCKQUOTE>
	<P>Unpacks bit packed data.<BR>
	Input: r0 = source, r1 = dest, r2 = unpack parameters

</BLOCKQUOTE>

<P>0x11: LZ77UnCompWRAM


<BLOCKQUOTE>
	<P>Uncompresses LZSS data 8 bits at a time<BR>
	Input: r0 = source address, r1 = dest address<BR>
	

</BLOCKQUOTE>

<P>0x12: LZ77UnCompVRAM


<BLOCKQUOTE>
	<P>Uncompresses LZSS data 16 bits at a time<BR>
	Input: r0 = source address, r1 = dest address<BR>
	<BR>
	<FONT SIZE="2">Note: The LZ77 decompressors actually decompress LZSS, not LZ77, which is slightly different. You
	will have to look on the web to find the algorithm as it is beyond the scope of this document. The following assumes
	a general famliarity with LZSS. <BR>
	<BR>
	On the GBA, the ring buffer or &quot;window&quot; is of size 4096, the minumim compressed length is 3 and the maximum
	compressed length is 18. Looking into a compressed buffer you will find the size of the uncompressed memory in
	bytes 2, 3, and 4 (I'm not sure what the first byte does, but it seems to always be set to &quot;01&quot;), followed
	by the coded data. This is divided up into sections consisting of an 8 bit key followed by a corresponding eight
	items of varying size. The upper bits in the key correspond to the items with lower addresses and vice versa. For
	each bit set in the key, the corresponding item will be 16 bits; the top bits four being the number of bytes to
	output, minus 3, and the bottom sixteen bits being the offset behind the current window position from which to
	output. For each bit which is not set, the corresponding item is an uncompressed byte and gets sent to the output.<BR>
	<BR>
	Thanks to Markus for providing me with some source that helped me figure out all of this.</FONT>

</BLOCKQUOTE>

<P><BR>
0x13: HuffUnComp


<BLOCKQUOTE>
	<P>Unpacks data compressed with Huffman and writes it 32-bits at a time.<BR>
	Input: r0 = source address, r1 = dest address

</BLOCKQUOTE>

<P>0x14: RLUnCompWRAM


<BLOCKQUOTE>
	<P>Uncompresses RLE data 8 bits at a time<BR>
	Input: r0 = source address, r1 = dest address

</BLOCKQUOTE>

<P>0x15: RLUnCompVRAM


<BLOCKQUOTE>
	<P>Uncompresses RLE data 16 bits at a time<BR>
	Input: r0 = source address, r1 = dest address

</BLOCKQUOTE>

<P>0x16: Diff8bitUnFilterWRAM 


<BLOCKQUOTE>
	<P>Unpacks data filtered with 8-bit difference and writes it 8-bits at a time.<BR>
	Input: r0 = source, r1 = dest

</BLOCKQUOTE>

<P><BR>
0x17: Diff8bitUnFilterVRAM 


<BLOCKQUOTE>
	<P>Unpacks data filtered with 8-bit difference and writes it 16-bits at a time.<BR>
	Input: r0 = source, r1 = dest

</BLOCKQUOTE>

<P>0x18: Diff16bitUnFilter 


<BLOCKQUOTE>
	<P>Unpacks data filtered with 16-bit difference and writes it 16-bits at a time.<BR>
	Input: r0 = source, r1 = dest

</BLOCKQUOTE>

<P>0x19: SoundBiasChange 


<BLOCKQUOTE>
	<P>Sets the sound bias from 0 to 0x200 or from 0x200 to 0 depending on the value of R0.<BR>
	Input: r0 = 0 to set it to 0, other values to set it to 0x200

</BLOCKQUOTE>

<P>0x1A: SoundDriverInit 


<BLOCKQUOTE>
	<P>Initializes the built in sound driver.<BR>
	Input: r0 = SoundArea

</BLOCKQUOTE>

<P>0x1B: SoundDriverMode 


<BLOCKQUOTE>
	<P>Sets the operation of the built in sound driver.<BR>
	Input: r0 = operation mode

</BLOCKQUOTE>

<P>0x1C: SoundDriverMain 


<BLOCKQUOTE>
	<P>Main function of the built in sound driver that is called by applications every VBLANK period to render the
	sound.

</BLOCKQUOTE>

<P>0x1D: SoundDriverVSync <BR>
0x1E: SoundChannelClear <BR>
0x1F: MIDIKey2Freq <BR>
Ox20: MusicPlayerOpen <BR>
0x21: MusicPlayerStart <BR>
0x22: MusicPlayerStop <BR>
0x23: MusicPlayerContinue <BR>
0x24: MusicPlayerFadeOut <BR>
0x25: MultiBoot <BR>
0x26: ?? <BR>
0x27: ?? <BR>
0x28: SoundDriverVSyncOff <BR>
0x29: SoundDriverVSyncOn <BR>
<BR>
?: FIQMasterEnable
<H2><BR>
<BR>
10. <A NAME="Memory-Mapped Hardware Registers"></A>Memory-Mapped Hardware Registers</H2>
<P>The following section describes the function of each of the memory-mapped addresses in IO RAM. The register
naming scheme is based on a variant of the popular <A HREF="gba.h">gba.h</A> by Eloist (specifically, that used
by Uze in the examples on his Audio Advance site).<BR>
<BR>
The notation for each entry is as follows:</P>
<PRE>                           <FONT COLOR="#FF0000">R</FONT>  <FONT COLOR="#777777">&lt;- </FONT>'<FONT COLOR="#FF0000">R</FONT>' <FONT
COLOR="#555555">means &quot;Read Only&quot;, '</FONT><FONT COLOR="#CC9900">W</FONT><FONT COLOR="#555555">' means &quot;Write Only&quot;</FONT>
F E D C  B A 9 8  7 6 5 4  3 2 1 0   <FONT COLOR="#555555">&lt;- These are the bits</FONT>
<FONT COLOR="#008800">W</FONT> <FONT COLOR="#0099FF">V</FONT> <FONT COLOR="#9900CC">U</FONT> <FONT COLOR="#FF0099">S</FONT>  <FONT
COLOR="#FF3300">L</FONT> <FONT COLOR="#008800">K</FONT> <FONT COLOR="#0099FF">J</FONT> <FONT COLOR="#9900CC">I</FONT>  <FONT
COLOR="#FF0099">F</FONT><FONT COLOR="#009999"> </FONT><FONT COLOR="#FF3300">D</FONT> <FONT COLOR="#008800">B</FONT><FONT
COLOR="#9900CC"> </FONT><FONT COLOR="#0099FF">A</FONT><FONT COLOR="#9900CC">  C</FONT> <FONT COLOR="#FF0099">M M M</FONT>   <FONT
COLOR="#555555">&lt;- These letters are used in the key
                                     Entries marked with an '</FONT><FONT COLOR="#BBBBBB">X</FONT><FONT COLOR="#555555">' usually 
                                     serve no function, are unwriteable,
                                     and remain at 0.</FONT></PRE>
<PRE>0-2 <FONT COLOR="#FF0099">(M)</FONT>   = The video mode. See <A HREF="#Mode 0">video modes</A> list above. <FONT
COLOR="#555555">&lt;- The key for each bit field</FONT>
</PRE>
<H3><BR>

<HR ALIGN="CENTER">
<B><BR>
Addresses: 0x04000000 - 0x4000054 - <A NAME="Graphics Hardware Registers"></A>Graphics Hardware Registers</B></H3>
<P><B><BR>
Address: 0x4000000 - <A NAME="REG_DISPCNT"></A>REG_DISPCNT (The display control register)</B></P>
<PRE>                        <FONT COLOR="#FF0000">   R</FONT>
F E D C  B A 9 8  7 6 5 4  3 2 1 0<FONT COLOR="#BBBBBB"> </FONT>
<FONT COLOR="#008800">W</FONT> <FONT COLOR="#0099FF">V</FONT> <FONT COLOR="#9900CC">U</FONT> <FONT COLOR="#FF0099">S</FONT>  <FONT
COLOR="#FF3300">L</FONT> <FONT COLOR="#008800">K</FONT> <FONT COLOR="#0099FF">J</FONT> <FONT COLOR="#9900CC">I</FONT>  <FONT
COLOR="#FF0099">F</FONT><FONT COLOR="#009999"> </FONT><FONT COLOR="#FF3300">D</FONT> <FONT COLOR="#008800">B</FONT><FONT
COLOR="#9900CC"> </FONT><FONT COLOR="#0099FF">A</FONT><FONT COLOR="#9900CC">  C</FONT> <FONT COLOR="#FF0099">M M M</FONT> </PRE>
<PRE>0-2 <FONT COLOR="#FF0099">(M)</FONT> = The video mode. See <A HREF="#Mode 0">video modes</A> list above. 
3 <FONT COLOR="#9900CC">  (C)</FONT> = Game Boy Color mode. Read only - should stay at 0. 
4 <FONT COLOR="#0099FF">  (A)</FONT> = This bit controls the starting address of the bitmap in bitmapped modes
          and is used for page flipping. See the description of the specific
          <A HREF="#Video Modes">video mode</A> for details. 
5   <FONT COLOR="#008800">(B)</FONT> = Force processing during hblank. Setting this causes the display
          controller to process data earlier and longer, beginning from the end of
          the previous scanline up to the end of the current one. This added
          processing time can help prevent flickering when there are too many
          sprites on a scanline.
6   <FONT COLOR="#FF3300">(D)</FONT> = Sets whether <A HREF="#OAM (sprites)">sprites</A> stored in VRAM use 1 dimension or 2.
          1 - 1d: tiles are are stored sequentially 
          0 - 2d: each row of tiles is stored 32 x 64 bytes in from the start of the
          previous row.</PRE>
<PRE>7   (<FONT COLOR="#FF0099">F)</FONT> = Force the display to go blank when set. This can be used to save power 
          when the display isn't needed, or to blank the screen when it is being
          built up (such as in mode 3, which has only one framebuffer). On the SNES,
          transfers rates to VRAM were improved during a forced blank; it is logical
          to assume that this would also hold true on the GBA.

8 <FONT COLOR="#9900CC">  (I)</FONT> = If set, enable display of BG0. 
9   <FONT COLOR="#0099FF">(J)</FONT> = If set, enable display of BG1. 
A <FONT COLOR="#008800">  (K)</FONT> = If set, enable display of BG2. 
B   (<FONT COLOR="#FF3300">L)</FONT> = If set, enable display of BG3. 
C <FONT COLOR="#FF0099">  (S)</FONT> = If set, enable display of <A HREF="#OAM (sprites)">OAM (sprites)</A>. 
D <FONT COLOR="#9900CC">  (U</FONT>) = Enable Window 0
E <FONT COLOR="#0099FF">  (V)</FONT> = Enable Window 1 
F <FONT COLOR="#008800">  (W)</FONT> = Enable Sprite Windows </PRE>
<P><BR>
<BR>
<B>Address: 0x4000004 - <A NAME="REG_STAT"></A>REG_DISPSTAT</B></P>
<PRE>                <FONT COLOR="#FF0000">      </FONT>       <FONT COLOR="#FF0000">R R R</FONT>
F E D C  B A 9 8  7 6 5 4  3 2 1 0 
<FONT COLOR="#9900CC">T T T T  T T T T</FONT> <FONT COLOR="#BBBBBB"> X X</FONT><FONT COLOR="#663300"> </FONT><FONT
COLOR="#FF0099">Y</FONT> <FONT COLOR="#FF3300">H</FONT>  <FONT COLOR="#008800">V</FONT> <FONT COLOR="#0099FF">Z</FONT> <FONT
COLOR="#9900CC">G</FONT> <FONT COLOR="#FF0099">W</FONT> </PRE>
<PRE>0   <FONT COLOR="#FF0099">(W)</FONT> = V Refresh status. This will be 0 during VDraw, and 1 during VBlank. 
          VDraw lasts for 160 scanlines; VBlank follows after that and lasts 68
          scanlines. Checking this is one alternative to checking <A HREF="#REG_VCOUNT">REG_VCOUNT</A>. 

1 <FONT COLOR="#9900CC">  (G)</FONT> = H Refresh status. This will be 0 during HDraw, and 1 during HBlank HDraw
          lasts for approximately 1004 cycles; HBlank follows, and lasts
          approximately 228 cycles, though the time and length of HBlank may in
          fact vary based on the number of sprites and on rotation/scaling/blending
          effects being performed on the current line. 

2 <FONT COLOR="#0099FF">  (Z)</FONT> = VCount Triggered Status. Gets set to 1 when a Y trigger interrupt occurs. 
3 <FONT COLOR="#008800">  (V)</FONT> = Enables LCD's VBlank <A HREF="#Hardware Interrupts">IRQ</A>. This interrupt goes off at the start of VBlank. 
4 <FONT COLOR="#FF3300">  (H)</FONT> = Enables LCD's HBlank <A HREF="#Hardware Interrupts">IRQ</A>. This interrupt goes off at the start of HBlank. 
5 <FONT COLOR="#FF0099">  (Y)</FONT> = Enable VCount trigger <A HREF="#Hardware Interrupts">IRQ</A>. Goes off when VCount line trigger is reached. 
8-F <FONT COLOR="#9900CC">(T)</FONT> = Vcount line trigger. Set this to the VCount value you wish to trigger an
          interrupt. </PRE>
<P><BR>
<BR>
<B>Address: 0x4000006 - LCY / <A NAME="REG_VCOUNT"></A>REG_VCOUNT (Read Only)</B><BR>
<BR>
This location stores the current y location of the LCD hardware. It is incremented as the lines are drawn. The
160 lines of display are followed by 68 lines of Vblank period, before the whole thing starts again for the next
frame. Waiting for this register to reach 160 is one way to synchronize a program to 60Hz.
<H3>
<HR ALIGN="CENTER">
<B><BR>
Addresses: 0x400008 - 0x400001E - <A NAME="Background Registers"></A>Background Registers</B></H3>
<P><BR>
<B>Address: 0x4000008 - <A NAME="REG_BG0"></A>REG_BG0CNT <BR>
Address: 0x400000A - <A NAME="REG_BG1"></A>REG_BG1CNT <BR>
Address: 0x400000C - <A NAME="REG_BG2"></A>REG_BG2CNT <BR>
Address: 0x400000E - <A NAME="REG_BG3"></A>REG_BG3CNT </B><BR>
<BR>
These addresses set up the four background layers. The format is:</P>
<PRE>    <FONT COLOR="#DD0000">?</FONT>               
F E D C  B A 9 8  7 6 5 4  3 2 1 0 
<FONT COLOR="#9900CC">Z Z</FONT> <FONT COLOR="#FF0099">V</FONT> <FONT COLOR="#FF3300">M  M M M M</FONT> <FONT COLOR="#008800"> A</FONT> <FONT
COLOR="#0099FF">C</FONT> <FONT COLOR="#BBBBBB">X X  </FONT><FONT COLOR="#9900CC">S S</FONT> <FONT COLOR="#FF0099">P P</FONT> 

0-1 <FONT COLOR="#FF0099">(P)</FONT> = <A NAME="Priority"></A>Priority - 00 highest, 11 lowest
          Priorities are ordered as follows:

          &quot;Front&quot;
          1. Sprite with priority 0
          2. BG with     priority 0

          3. Sprite with priority 1
          4. BG with     priority 1

          5. Sprite with priority 2
          6. BG with     priority 2

          7. Sprite with priority 3
          8. BG with     priority 3

          9. Backdrop
          &quot;Back&quot;

          When multiple backgrounds have the same priority, the order
          from front to back is:  BG0, BG1, BG2, BG3.  Sprites of the same
          priority are ordered similarly, with the first sprite in OAM
          appearing in front.          

2-3 <FONT COLOR="#9900CC">(S)</FONT> = Starting address of character tile data
          Address = 0x6000000 + S * 0x4000
6 <FONT COLOR="#0099FF">  (C)</FONT> = Mosiac effect - 1 on, 0 off

7 <FONT COLOR="#008800">  (A)</FONT> = <A HREF="#Palette">Color palette</A> type -
          1 - standard 256 color pallete
          0 - each tile uses one of 16 different 16 color palettes (no effect on
              rotates/scale backgrounds, which are always 256 color)

8-C <FONT COLOR="#FF3300">(M)</FONT> = Starting address of character tile map
          Address = 0x6000000 + M * 0x800
D   <FONT COLOR="#FF0099">(V)</FONT> = Screen Over. Used to determine whether <A HREF="#Scale/Rotate Backgrounds">rotational backgrounds</A> get tiled
          repeatedly at the edges or are displayed as a single &quot;tile&quot; with the area
          outside transparent. This is forced to 0 (read only) for backgrounds 
          0 and 1 (only).

E-F <FONT COLOR="#9900CC">(Z)</FONT> = Size of tile map
          For <A HREF="#Text Backgrounds">&quot;text&quot; backgrounds</A>: 
          00 : 256x256 (32x32 tiles) 
          01 : 512x256 (64x32 tiles) 
          10 : 256x512 (32x64 tiles) 
          11 : 512x512 (64x64 tiles) 

          For <A HREF="#Scale/Rotate Backgrounds">rotational backgrounds</A>: 
          00 : 128x128 (16x16 tiles) 
          01 : 256x256 (32x32 tiles) 
          10 : 512x512 (64x64 tiles)
          11 : 1024x1024 (128x128 tiles)</PRE>
<P><BR>
<B>Address: 0x4000010 - <A NAME="REG_BG0SCX"></A>REG_BG0HOFS Horizontal scroll co-ordinate for BG0 (Write Only)<BR>
Address: 0x4000012 - <A NAME="REG_BG0SCY"></A>REG_BG0VOFS Vertical scroll co-ordinate for BG0 (Write Only)<BR>
Address: 0x4000014 - REG_BG1HOFS Horizontal scroll co-ordinate for BG1 (Write Only)<BR>
Address: 0x4000016 - REG_BG1VOFS Vertical scroll co-ordinate for BG1 (Write Only)<BR>
Address: 0x4000018 - REG_BG2HOFS Horizontal scroll co-ordinate for BG2 (Write Only)<BR>
Address: 0x400001A - REG_BG2VOFS Vertical scroll co-ordinate for BG2 (Write Only)<BR>
Address: 0x400001C - REG_BG3HOFS Horizontal scroll co-ordinate for BG3 (Write Only)<BR>
Address: 0x400001E - REG_BG3VOFS Vertical scroll co-ordinate for BG3 (Write Only)</B></P>
<PRE>F E D C  B A 9 8  7 6 5 4  3 2 1 0 
<FONT COLOR="#BBBBBB">X X X X  X X </FONT><FONT COLOR="#FF0099">S S  S S S S  S S S S</FONT> </PRE>
<PRE>0-9<FONT COLOR="#FF0099"> (S)</FONT> = Scroll value (pixels) </PRE>
<P><BR>
These registers are only effective for <A HREF="#Text Backgrounds">text backgrounds</A>; they set the pixel that
is displayed in the top left hand corner of the GBA's display. In other words, a value of -5, -5 puts the upper
left hand corner of your background at x=5,y=5. All four BG planes wrap when they reach their right or bottom edges.
<H3><BR>

<HR ALIGN="CENTER">
<B><BR>
Addresses: 0x4000020 - 0x4000026 / 0x4000030 - 0x4000036 - <A NAME="Background Rotation/Scaling Regi"></A>Background
Rotation/Scaling Registers (Write Only)</B></H3>
<P>These registers affect the translation, rotation, and scaling of tile-based <A HREF="#Scale/Rotate Backgrounds">rotate/scale
backgrounds</A> as well as the <A HREF="#Bitmapped Backgrounds">bitmapped backgrounds</A> (which should be treated
as BG2 for this purpose). The function of these registers is very hard to describe in words but easy to see the
effects of on screen. I highly recommend checking out Stephen Stair's RSDemo - it lets you see the contents of
the regs as you modify them as well as the effect they have on the background. Should also be somewhat useful for
figuring out sprite rotation and scaling.</P>
<PRE>F E D C  B A 9 8  7 6 5 4  3 2 1 0 
<FONT COLOR="#0099FF">S</FONT> <FONT COLOR="#9900CC">I I I  I I I I</FONT> <FONT COLOR="#FF0099"> F F F F  F F F F</FONT> </PRE>
<PRE>0-7 <FONT COLOR="#FF0099">(F)</FONT> = Fraction 
8-E <FONT COLOR="#9900CC">(I)</FONT> = Integer 
F   <FONT COLOR="#0099FF">(S)</FONT> = Sign bit 
</PRE>
<P>These registers apply only to <A HREF="#Scale/Rotate Backgrounds">Rotate/Scale backgrounds</A>. Individual descriptions
follow: <BR>
<BR>
<B>Address: 0x4000020 - <A NAME="REG_BG2DX/PA"></A>REG_BG2PA (BG2 Read Source Pixel X Increment)(Write Only) <BR>
Address: 0x4000030 - <A NAME="REG_BG3DX/PA"></A>REG_BG3PA (BG3 Read Source Pixel X Increment) (Write Only)</B><BR>
<BR>
The effect of these registers is to scale the background (relative to the upper left corner) in the x direction
by an amount equal to 1/(register value). <BR>
<BR>
<B>Address: 0x4000022 - <A NAME="REG_BG2DMX/PB"></A>REG_BG2PB (BG2 Write Destination Pixel X Increment) (Write
Only)<BR>
Address: 0x4000032 - <A NAME="REG_BG3DMX/PB"></A>REG_BG3PB (BG3 Write Destination Pixel X Increment) (Write Only)</B><BR>
<BR>
The effect of these registers is to shear the x coordinates of the background over y, relative to the upper left
corner. A value of 0 will result in no shearing, a value of 1.00 will make the background appear to be sheared
left as you go down the screen, and a value of -1 will make the background appear sheared right as you go down
the screen. <BR>
<BR>
<B>Address: 0x4000024 - <A NAME="REG_BG2DY/PC"></A>REG_BG2PC (BG2 Read Source Pixel Y Increment) (Write Only)<BR>
Address: 0x4000034 - <A NAME="REG_BG3DY/PC"></A>REG_BG3PC</B> <B>(BG3 Read Source Pixel Y Increment) (Write Only)</B><BR>
<BR>
The effect of these registers is to shear the y coordinates of the background over x, relative to the upper left
corner. A value of 0 will result in no shearing, a value of 1.00 will make the background appear to be sheared
upwards to the right, and a value of -1 will make the background appear sheared downwards and to the right. <BR>
<BR>
<B>Address: 0x4000026 - REG_<A NAME="REG_BG2DMY/PD"></A>BG2PD (BG2 Write Destination Pixel Y Increment) (Write
Only)<BR>
Address: 0x4000036 - REG_<A NAME="REG_BG3DMY/PD"></A>BG3PD (BG3 Write Destination Pixel Y Increment) (Write Only)</B><BR>
<BR>
The effect of these registers is to scale the background in the y direction (relative to the upper left corner)
by an amount equal to 1/(register value). <BR>
<BR>

<HR ALIGN="CENTER">
<BR>
<B>Address: 0x4000028 - <A NAME="REG_BG2X"></A>REG_BG2X (X Coordinate for BG2 Rotational Background)(Write Only)<BR>
Address: 0x4000038 - <A NAME="REG_BG3X"></A>REG_BG3X (X Coordinate for BG3 Rotational Background)(Write Only)<BR>
<BR>
Address: 0x400002C - <A NAME="REG_BG2Y"></A>REG_BG2Y (Y Coordinate for BG2 Rotational Background)(Write Only)<BR>
Address: 0x400003C - <A NAME="REG_BG3Y"></A>REG_BG3Y (Y Coordinate for BG3 Rotational Background)(Write Only)</B></P>
<PRE>31 30 29 28  27 26 25 24  23 22 21 20  19 18 17 16  15 14 13 12  11 10 9 8  7 6 5 4  3 2 1 0
<FONT COLOR="#BBBBBB">X  X  X  X </FONT> <FONT COLOR="#0099FF"> S</FONT>  <FONT COLOR="#9900CC">I  I  I   I  I  I  I   I  I  I  I   I  I  I  I   I  I  I I</FONT> <FONT
COLOR="#9900CC"> </FONT><FONT COLOR="#FF0099">F F F F  F F F F</FONT> </PRE>
<PRE>0-7 <FONT COLOR="#FF0099"> (F)</FONT> - Fraction 
8-26 <FONT COLOR="#9900CC">(I)</FONT> - Integer 
27 <FONT COLOR="#0099FF">  (S)</FONT> - Sign bit </PRE>
<P><BR>
These registers define the location of the pixel that appears at 0,0. They are very similar to the background scrolling
registers, <A HREF="#REG_BG0SCX">REG_HOFS</A> and <A HREF="#REG_BG0SCY">REG_VOFS</A>, which become disabled when
a <A HREF="#Scale/Rotate Backgrounds">rotate/ scale background</A> is in use. <BR>
<BR>
<BR>

<HR ALIGN="CENTER">

<H3><B>Addresses: 0x4000040 - 0x400004A - <A NAME="Windowing Registers"></A>Windowing Registers</B></H3>
<P><BR>
<B>Address: 0x4000040 - <A NAME="REG_WIN0_H"></A>REG_WIN0H (</B><A HREF="#Windowing"><B>Window</B></A><B> 0 X Coordinates)
(Write Only)<BR>
Address: 0x4000042 - <A NAME="REG_WIN1_H"></A>REG_WIN1H (</B><A HREF="#Windowing"><B>Window</B></A><B> 1 X Coordinates)(Write
Only)</B></P>
<PRE>F E D C  B A 9 8  7 6 5 4  3 2 1 0 
<FONT COLOR="#9900CC">L L L L  L L L L</FONT> <FONT COLOR="#FF0099"> R R R R  R R R R</FONT> </PRE>
<PRE>0-7 <FONT COLOR="#FF0099">(R)</FONT> = X coordinate for the rightmost side of the window 
8-F <FONT COLOR="#9900CC">(L)</FONT> = X coordinate for the leftmost side of the window </PRE>
<P><BR>
<B>Address: 0x4000044 - <A NAME="REG_WIN0_V"></A>REG_WIN0V (</B><A HREF="#Windowing"><B>Window</B></A><B> 0 Y Coordinates)
(Write Only)<BR>
Address: 0x4000046 - <A NAME="REG_WIN1_V"></A>REG_WIN1V (</B><A HREF="#Windowing"><B>Window</B></A><B> 1 Y Coordinates)(Write
Only)</B></P>
<PRE>F E D C  B A 9 8  7 6 5 4  3 2 1 0 
<FONT COLOR="#9900CC">T T T T  T T T T</FONT>  <FONT COLOR="#FF0099">B B B B  B B B B</FONT> </PRE>
<PRE>0-7 <FONT COLOR="#FF0099">(B)</FONT> = Y coordinate for the bottom of the window 
8-F <FONT COLOR="#9900CC">(T)</FONT> = Y coordinate for the top of the window </PRE>
<P><BR>
<B>Address: 0x4000048 - <A NAME="REG_WIN_IN"></A>REG_WININ (Inside </B><A HREF="#Windowing"><B>Window</B></A><B>
Settings)</B></P>
<PRE>F E D C  B A 9 8  7 6 5 4  3 2 1 0 
<FONT COLOR="#BBBBBB">X X</FONT> <FONT COLOR="#9900CC">T</FONT> <FONT COLOR="#FF0099">S</FONT> <FONT COLOR="#FF3300"> R</FONT> <FONT
COLOR="#008800">Q</FONT> <FONT COLOR="#0099FF">P</FONT> <FONT COLOR="#9900CC">O</FONT> <FONT COLOR="#BBBBBB"> X X</FONT> <FONT
COLOR="#FF0099">L</FONT> <FONT COLOR="#FF3300">K</FONT>  <FONT COLOR="#008800">J</FONT> <FONT COLOR="#0099FF">I</FONT> <FONT
COLOR="#9900CC">H</FONT> <FONT COLOR="#FF0099">G</FONT> </PRE>
<PRE>0 <FONT COLOR="#FF0099">(G)</FONT> = BG0 in win0 
1 <FONT COLOR="#9900CC">(H)</FONT> = BG1 in win0 
2 <FONT COLOR="#0099FF">(I)</FONT> = BG2 in win0 
3 <FONT COLOR="#008800">(J)</FONT> = BG3 in win0 
4 <FONT COLOR="#FF3300">(K)</FONT> = Sprites in win0 
5 <FONT COLOR="#FF0099">(L)</FONT> = Blends in win0 
8 <FONT COLOR="#9900CC">(O)</FONT> = BG0 in win1 
9 <FONT COLOR="#0099FF">(P)</FONT> = BG1 in win1 
A <FONT COLOR="#008800">(Q)</FONT> = BG2 in win1 
B <FONT COLOR="#FF3300">(R)</FONT> = BG3 in win1 
C <FONT COLOR="#FF0099">(S)</FONT> = Sprites in win1 
D <FONT COLOR="#9900CC">(T)</FONT> = Blends in win1 </PRE>
<P><BR>
<BR>
<B>Address: 0x400004A - <A NAME="REG_WIN_OUT"></A>REG_WINOUT (Outside </B><A HREF="#Windowing"><B>Window</B></A><B>
and Sprite </B><A HREF="#Windowing"><B>Window</B></A><B>)</B></P>
<PRE><FONT COLOR="#FF0000">
</FONT>F E D C  B A 9 8  7 6 5 4  3 2 1 0 
<FONT COLOR="#BBBBBB">X X </FONT><FONT COLOR="#9900CC">T</FONT> <FONT COLOR="#FF0099">S</FONT> <FONT COLOR="#FF3300"> R</FONT> <FONT
COLOR="#008800">Q</FONT> <FONT COLOR="#0099FF">P</FONT> <FONT COLOR="#9900CC">O</FONT> <FONT COLOR="#BBBBBB"> X X </FONT><FONT
COLOR="#FF0099">L</FONT> <FONT COLOR="#FF3300">K</FONT> <FONT COLOR="#008800"> J</FONT> <FONT COLOR="#0099FF">I</FONT> <FONT
COLOR="#9900CC">H</FONT> <FONT COLOR="#FF0099">G</FONT> </PRE>
<PRE>0 <FONT COLOR="#FF0099">(G)</FONT> = BG0 outside
1 <FONT COLOR="#9900CC">(H)</FONT> = BG1 outside 
2 <FONT COLOR="#0099FF">(I)</FONT> = BG2 outside 
3 <FONT COLOR="#008800">(J)</FONT> = BG3 outside 
4 <FONT COLOR="#FF3300">(K)</FONT> = Sprites in win0 
5 <FONT COLOR="#FF0099">(L)</FONT> = Blends in win0 
8 <FONT COLOR="#9900CC">(O)</FONT> = BG0 in sprite win 
9 <FONT COLOR="#0099FF">(P)</FONT> = BG1 in sprite win 
A <FONT COLOR="#008800">(Q)</FONT> = BG2 in sprite win 
B <FONT COLOR="#FF3300">(R)</FONT> = BG3 in sprite win 
C <FONT COLOR="#FF0099">(S)</FONT> = Sprites in sprite win 
D <FONT COLOR="#9900CC">(T)</FONT> = Blends in sprite win </PRE>
<P><BR>

<HR ALIGN="CENTER">

<H3><B>Addresses: 0x400004C - 0x4000054 - <A NAME="Effects Registers"></A>Effects Registers</B></H3>
<P><BR>
<B>Address: 0x400004C - <A NAME="REG_MOSAIC"></A>REG_MOSAIC (Write Only)</B></P>
<PRE>F E D C  B A 9 8  7 6 5 4  3 2 1 0 
<FONT COLOR="#008800">V V V V</FONT> <FONT COLOR="#0099FF"> U U U U</FONT>  <FONT COLOR="#9900CC">J J J J</FONT> <FONT
COLOR="#FF0099"> I I I I</FONT> </PRE>
<PRE>0-3 <FONT COLOR="#FF0099">(I)</FONT> = BG X Size 
4-7 <FONT COLOR="#9900CC">(J)</FONT> = BG Y Size 
8-B <FONT COLOR="#0099FF">(U)</FONT> = Sprite X Size 
C-F <FONT COLOR="#008800">(V)</FONT> = Sprite Y Size </PRE>
<P><BR>
Use this register to control the size of the mosaic on backgrounds/sprites that have mosaic enabled.. <BR>
<BR>
<BR>
<B>Address: 0x4000050 - <A NAME="REG_BLDCNT"></A>REG_BLDMOD</B></P>
<PRE>F E D C  B A 9 8  7 6 5 4  3 2 1 0 
<FONT COLOR="#BBBBBB">X X</FONT> <FONT COLOR="#0099FF">T</FONT> <FONT COLOR="#9900CC">S</FONT> <FONT COLOR="#FF0099"> R</FONT> <FONT
COLOR="#FF3300">Q</FONT> <FONT COLOR="#008800">P</FONT> <FONT COLOR="#0099FF">O</FONT> <FONT COLOR="#9900CC"> M M</FONT> <FONT
COLOR="#FF0099">L</FONT> <FONT COLOR="#FF3300">K</FONT>  <FONT COLOR="#008800">J</FONT> <FONT COLOR="#0099FF">I</FONT> <FONT
COLOR="#9900CC">H</FONT> <FONT COLOR="#FF0099">G</FONT> </PRE>
<PRE>0 <FONT COLOR="#FF0099">  (G)</FONT> = Blend BG0 (source) 
1 <FONT COLOR="#9900CC">  (H)</FONT> = Blend Bg1 (source) 
2<FONT COLOR="#0099FF">   (I)</FONT> = Blend BG2 (source) 
3<FONT COLOR="#008800">   (J)</FONT> = Blend BG3 (source) 
4 <FONT COLOR="#FF3300">  (K)</FONT> = Blend sprites (source) 
5   <FONT COLOR="#FF0099">(L)</FONT> = Blend backdrop (source) 
6-7 <FONT COLOR="#9900CC">(M)</FONT> = Blend Mode
          
          There are four different modes: 
          00: All effects off 
          01: alpha blend 
          10: lighten (fade to white) 
          11: darken (fade to black)</PRE>
<PRE>8 <FONT COLOR="#0099FF">  (O)</FONT> = Blend BG0 (target) 
9 <FONT COLOR="#008800">  (P)</FONT> = Blend BG1 (target) 
A <FONT COLOR="#FF3300">  (Q)</FONT> = Blend BG2 (target) 
B <FONT COLOR="#FF0099">  (R)</FONT> = Blend BG3 (target) 
C <FONT COLOR="#9900CC">  (S)</FONT> = Blend sprites (target)
D <FONT COLOR="#0099FF">  (T)</FONT> = Blend backdrop (target)</PRE>
<P><BR>
Use this register to determine the blending mode and which layer(s) you wish to perform blending on. In the case
of alpha blends (Mode 01), specify the layers that are &quot;on top&quot; using the source flags (bits 0 - 5) and
the layers that are on the bottom using the target flags (bits 8-13). The target layer must be below the source
layer in terms of its <A HREF="#Priority">priority</A>, or the blend will not take effect. Other things to note
about alpha blends:


<BLOCKQUOTE>
	<P>- If there is more than one target layer, the blend will only occur for a target with lower priority in areas
	where it shows through targets of higher priority due to the transparent pixel being set<BR>
	- Source layers will only blend with areas of a target layer that are visible beneath them. If another layer is
	blocking the way (even if it is another source layer), there will be no blend and the original source color will
	be drawn.<BR>
	- As a result of these two conditions, it is never possible for any given pixel to be a blend of more than 2 layers.
	This eliminates the possiblity of using these registers to have 3 or more layers of translucent graphics showing
	through one another.<BR>
	- A layer cannot blend with itself<BR>
	<BR>
	- If an obj has semi-transparency enabled, it will blend normally (as if it were specified as a source layer)<BR>
	- Unfortunately, it is not possible to alpha blend sprites against one another, no matter how your prioritize them.
	Alpha blended sprites that are &quot;in front of&quot; other sprites will blend with the other target layers while
	still occluding the sprites behind them (i.e. it will look like the portion of the non-blended sprite that is behind
	the blended one has disappeared), for a most unnatural effect.

</BLOCKQUOTE>

<P><BR>
<BR>
<B>Address: 0x4000052 - <A NAME="REG_BLDALPHA"></A>REG_COLEV (Write Only)</B></P>
<PRE>F E D C  B A 9 8  7 6 5 4  3 2 1 0 
<FONT COLOR="#BBBBBB">X X X </FONT><FONT COLOR="#9900CC">B  B B B B</FONT><FONT COLOR="#BBBBBB">  X X X </FONT><FONT
COLOR="#FF0099">A  A A A A</FONT> </PRE>
<PRE>0-4 <FONT COLOR="#FF0099">(A)</FONT> = Coefficient A, the source pixel (layer above)
8-C <FONT COLOR="#9900CC">(B)</FONT> = Coefficient B, the target pixel (layer below)</PRE>
<P><BR>
Use this in conjunction with <A HREF="#REG_BLDCNT">REG_BLDCNT</A> to determine the amount of blending between layers.
An unblended pixel of normal intensity is is considered to have a coefficient of 16. Coefficient A and Coefficient
B determine the ratio of each of the sources that will get mixed into the final image. Thus, if A is 12 and B is
4, the resulting image will appear to be 12/16 the color of A and 4/16 the color of B. Note that A and B can add
up to be greater than 16 (for an additive or brightening effect) or less than 16 (for a darkening effect).<BR>
<BR>
<B>Address: 0x4000054 - <A NAME="REG_BLDY"></A>REG_COLEY (Write Only)</B></P>
<PRE>F E D C  B A 9 8  7 6 5 4  3 2 1 0 
<FONT COLOR="#BBBBBB">X X X X  X X X X  X X X </FONT><FONT COLOR="#FF0099">F  F F F F</FONT> </PRE>
<PRE>0-4 <FONT COLOR="#FF0099">(F)</FONT> = The lighten/darken value </PRE>
<P><BR>
This is the amount by which to lighten or darken the source layers (as specified in <A HREF="#REG_BLDCNT">REG_BLDCNT</A>)
.<BR>
The higher the value, the greater the fade. 16 is the peak fade value; values from 16 - 31 shade the layer with
either pure black (for a darken) or pure white (for a lighten).
<H3><BR>

<HR ALIGN="CENTER">
<BR>
Addresses 0x040000060 - 0x0400000A6 (<A NAME="Sound Controls"></A>Sound Controls: Partially unimplemented in CowBite)</H3>
<P>Note: I've obtained this info (most of it verbatim) from Uze's <A HREF="http://belogic.com/gba/">BeLogic</A>
unofficial GBA sound info site, which gives a much more thorough explanation as well as some sample source code
and demos. Thanks to Uze for providing such a great resource on GBA sound.<BR>
<B><BR>
Address: 0x04000060 - <A NAME="REG_SOUND1CNT_L"></A>REG_SOUND1CNT_L (Sound 1 Sweep control) (Unimplemented in CowBite)</B></P>
<PRE>F E D C  B A 9 8  7 6 5 4  3 2 1 0 
<FONT COLOR="#BBBBBB">X X X X  X X X X  X </FONT><FONT COLOR="#0099FF">T T T</FONT> <FONT COLOR="#9900CC"> A</FONT> <FONT
COLOR="#FF0099">S S<B> </B>S</FONT>

0-2 <FONT COLOR="#FF0099">(S)</FONT> = Number of sweep shifts. These control the amount of change in 
          frequency (either increase or decrease) at each change. The wave's new
          period is given by: T=T&plusmn;T/(2<SUP>n</SUP>), where <I>n</I> is the sweep shift's value.

3 <FONT COLOR="#9900CC">  (A)</FONT> = Sweep increase or decrease. When decrementing, if the frequency value
          gets smaller than zero, the previous value is retained. When
          incrementing, if the frequency gets greater than the maximum frequency
          (131Khz or 2048 for the register value) the sound stops.
          0 - Addition (frequency increase)
          1 - Subtraction (frequency decrease)</PRE>
<PRE>4-6 <FONT COLOR="#0099FF">(T)</FONT> = Sweep Time. This is the delay between sweep shifts. After each delay,
          the frequency increments or decrements.
          000:  Disable sweep function
          001:  Ts=1 / 128khz (7.8 ms)
          010:  Ts=2 / 128khz (15.6 ms)
          011:  Ts=3 / 128 khz (23.4 ms)
          100:  Ts=4 / 128 khz (31.3 ms)
          101:  Ts=5 / 128 khz (39.1 ms)
          110:  Ts=6 / 128 khz (46.9 ms)
          111:  Ts=7 / 128 khz (54.7 ms)</PRE>
<P><BR>
Sound channel 1 produces a square wave with envelope and frequency sweep functions. This register controls the
frequency sweep function. When the sweep function is not required, set the sweep time to zero and set the increase/decrease
bit to 1. <BR>
<BR>
<B><BR>
Address: 0x04000062 - <A NAME="REG_SOUND1CNT_H"></A>REG_SOUND1CNT_H (Sound 1 Length, wave duty and envelope control)(Unimplemented
in CowBite)</B></P>
<PRE>                    <FONT COLOR="#CC9900">  W W  W W W W</FONT>
F E D C  B A 9 8  7 6 5 4  3 2 1 0 
<FONT COLOR="#FF3300">I I I I</FONT> <FONT COLOR="#008800"> M</FONT> <FONT COLOR="#0099FF">T T T</FONT>  <FONT
COLOR="#9900CC">D D</FONT> <FONT COLOR="#FF0099">L L  L L L L</FONT></PRE>
<PRE>0-5 <FONT COLOR="#FF0099">(L)</FONT> = Sound length. This is a 6 bit value obtained from the following
          formula: Sound length= (64-register value)*(1/256) seconds. After the
          sound length has been changed, the sound channel must be resetted via
          bit F of <A HREF="#REG_SOUND1CNT_X">REG_SOUND1CNT_X</A> (when using timed mode). 

6-7 <FONT COLOR="#9900CC">(D)</FONT> = Wave duty cycle. This controls the percentage of the ON state of the
          square wave.

          00 - 12.5%
          01 - 25%
          10 - 50%
          11 - 75%</PRE>
<PRE>8-A <FONT COLOR="#0099FF">(T)</FONT> = Envelope step time. This is the delay between successive envelope
          increase or decrease. It is given by the following formula: 
          Time=register value*(1/64) seconds. 

B <FONT COLOR="#008800">  (M)</FONT> = Envelope mode. Controls if the envelope is to increase or decrease in
          volume over time.
        
          0 - Envelope decreases
          1 - Envelope increases</PRE>
<PRE>C-F <FONT COLOR="#FF3300">(I)</FONT> = Initial Envelope value<B>. </B>1111 produces the maximum volume and 0000 mutes
          the sound. When sound 1 is playing, modifying the volume envelope bits
          has no effect until the sound is resetted.</PRE>
<P><B><BR>
<BR>
Address: 0x04000064 - <A NAME="REG_SOUND1CNT_X"></A>REG_SOUND1CNT_X (Sound 1 Frequency, reset and loop control)(Unimplemented
in CowBite)</B></P>
<PRE><FONT COLOR="#CC9900">W</FONT>         <FONT COLOR="#CC9900"> W W W  W W W W  W W W W</FONT>
F E D C  B A 9 8  7 6 5 4  3 2 1 0 
<FONT COLOR="#0099FF">R</FONT> <FONT COLOR="#9900CC">T</FONT> <FONT COLOR="#BBBBBB">X X  X</FONT> <FONT COLOR="#FF0099">F F F  F F F F  F F F F</FONT>

</PRE>
<PRE>0-A <FONT COLOR="#FF0099">(F)</FONT> = Sound frequency. The minimum frequency is 64Hz and the maximum is
          131Khz. Can be calculated from the following formula:
          F(hz)=4194304/(32*(2048-register value)).

E   <FONT COLOR="#9900CC">(T)</FONT> = Timed sound. When set to 0, sound 1 is played continuously regardless
          of the length data in <A HREF="#REG_SOUND1CNT_H">REG_SOUND1CNT_H</A>. When set to 1, sound is played
          for that specified length and after that, bit 0 of <A HREF="#REG_SOUNDCNT_X">REG_SOUNDCNT_X</A> is
          reset.
F<FONT COLOR="#0099FF">   (R)</FONT> = Sound reset. When set, sound resets and restarts at the specified
          frequency. When sound 1 is playing, modifying the volume envelope bits
          has no effect until the sound is resetted. Frequency and sound reset must
          be perfomed in a single write since both are write only. Frequency can
          always be changed without resetting the sound channel. </PRE>
<P><BR>
<B><BR>
Address: 0x04000068 - <A NAME="REG_SOUND2CNT_L"></A>REG_SOUND2CNT_L (Sound 2 Length, wave duty and envelope control)(Unimplemented
in CowBite)</B></P>
<PRE>                     <FONT COLOR="#CC9900"> W W  W W W W</FONT>
F E D C  B A 9 8  7 6 5 4  3 2 1 0 
<FONT COLOR="#FF3300">I I I I</FONT> <FONT COLOR="#008800"> M</FONT> <FONT COLOR="#0099FF">T T T</FONT> <FONT COLOR="#9900CC"> D D</FONT> <FONT
COLOR="#FF0099">L L  L L L L</FONT></PRE>
<PRE>0-5 <FONT COLOR="#FF0099">(L)</FONT> = Sound length. This is a 6 bit value obtained from the following
          formula:  Sound length= (64-register value)*(1/256) seconds.
          After the sound length has been changed, the sound channel must be
          resetted via bit F of <A HREF="#REG_SOUND2CNT_H">REG_SOUND1CNT_X</A> (when using timed mode). 

6-7 <FONT COLOR="#9900CC">(D)</FONT> = Wave duty cycle. This controls the percentage of the ON state of
          the square wave.
          
          00 - 12.5%
          01 - 25%
          10 - 50%
          11 - 75%</PRE>
<PRE>8-A <FONT COLOR="#0099FF">(T)</FONT> = Envelope step time. This is the delay between successive envelope increase
          or decrease. It is given by the following formula: Time=register value*(1/64)
          seconds. 

B   <FONT COLOR="#008800">(M)</FONT> = Envelope mode. Controls if the envelope is to increase or decrease in volume
          over time.
        
          0 - Envelope decreases
          1 - Envelope increases</PRE>
<PRE>C-F <FONT COLOR="#FF3300">(I)</FONT> = Initial Envelope value<B>. </B>1111 produces the maximum volume and 0000 mutes
          the sound. When sound 2 is playing, modifying the volume envelope bits has
          no effect until the sound is resetted.<B>
</B></PRE>
<P><B><BR>
Address: 0x0400006C- <A NAME="REG_SOUND2CNT_H"></A>REG_SOUND2CNT_H (Sound 2 Frequency, reset and loop control)(Unimplemented
in CowBite)</B></P>
<PRE><FONT COLOR="#CC9900">W</FONT>       <FONT COLOR="#CC9900">   W W W  W W W W  W W W W</FONT>
F E D C  B A 9 8  7 6 5 4  3 2 1 0 
<FONT COLOR="#0099FF">R</FONT> <FONT COLOR="#9900CC">T</FONT><FONT COLOR="#BBBBBB"> X X  X </FONT><FONT COLOR="#FF0099">F F F  F F F F  F F F F</FONT></PRE>
<PRE>0-A <FONT COLOR="#FF0099">(F)</FONT> = Sound frequency. The minimum frequency is 64Hz and the maximum is
         131Khz. Can be calculated from the following formula:
         F(hz)=4194304/(32*(2048-register value)).

E   <FONT COLOR="#9900CC">(T)</FONT> = Timed sound. When set to 0, sound 2 is played continuously regardless of
          the length data in <A HREF="#REG_SOUND2CNT_L">REG_SOUND2CNT_L</A>. When set to 1, sound is played for
          that specified length and after that, bit 1 of <A HREF="#REG_SOUNDCNT_X">REG_SOUNDCNT_X</A> is reset.

F <FONT COLOR="#0099FF">  (R)</FONT> = Sound reset. When set, sound resets and restarts at the specified
          frequency. When sound 2 is playing, modifying the volume envelope bits
          has no effect until the sound is resetted. Frequency and sound reset must
          be perfomed in a single write since both are write only. Frequency can
          always be changed without resetting the sound channel.</PRE>
<P><B><BR>
<BR>
Address: 0x04000070 - <A NAME="REG_SOUND3CNT_L"></A>REG_SOUND3CNT_L (Sound 3 Enable and wave ram bank control)(Unimplemented
in CowBite)</B></P>
<PRE>F E D C  B A 9 8  7 6 5 4  3 2 1 0 
<FONT COLOR="#BBBBBB">X X X X  X X X X</FONT> <FONT COLOR="#0099FF"> N</FONT> <FONT COLOR="#9900CC">S</FONT> <FONT
COLOR="#FF0099">M</FONT> <FONT COLOR="#BBBBBB">X  X X X X</FONT>

</PRE>
<PRE>5 <FONT COLOR="#FF0099">(M)</FONT> = Bank Mode (0 - 2 32 sample banks, 1 - 1 64 sample bank)<B>
</B>6 <FONT COLOR="#9900CC">(S)</FONT> = Bank Select<B>. </B>Controls which bank is active for playing/reloading. If set
        to 0, samples are played from bank 0 and writing to the Wave Ram will
        store the data in Bank 1, and vice-versa.
7 <FONT COLOR="#0099FF">(N)</FONT> = Sound Channel 3 output enable. When this is set and bit 15 from
        <A HREF="#REG_SOUND3CNT_X">REG_SOUND3CNT_X</A> is set, the sound starts to play.
</PRE>
<P>Sound channel 3 is a circuit that can produce an arbitrary wave pattern. Samples are 4 bit, 8 samples per word,
and are located in <A HREF="#REG_WAVE_RAM0_L">Wave Ram registers</A> from 0x400090 to 0x40009F. The Wave Ram is
banked, providing the ability to play a 64 samples pattern or to select between two 32 samples patterns (Bit 5).
Sound channel 3 always produces some audio artifacts (distortion) when sound is initialized. Fortunately, switching
banks does not require re-initialisation during playback, thus allowing for dynamic reloading of the Wave Ram without
generating any distortion.<BR>
<BR>
Both banks of Wave Ram are filled with zero upon initialization of the Gameboy, Bank 0 being selected. So writing
to bank 0 implies setting bit 6 to 1 before loading Wave Ram then set it back to 0 to play it.<BR>
<B><BR>
<BR>
Address: 0x04000072 - <A NAME="REG_SOUND3CNT_H"></A>REG_SOUND3CNT_H (Sound 3 Sound length and output level control)(Unimplemented
in CowBite)</B></P>
<PRE>                  <FONT COLOR="#CC9900">W W W W  W W W W</FONT>
F E D C  B A 9 8  7 6 5 4  3 2 1 0 
<FONT COLOR="#9900CC">R R R</FONT> <FONT COLOR="#BBBBBB">X  X X X X</FONT> <FONT COLOR="#FF0099"> L L L L  L L L L</FONT>

</PRE>
<PRE>0-7 <FONT COLOR="#FF0099">(L)</FONT> = Sound length. The sound length is an 8 bit value obtained from the 
          following formula:  Register=Note length (in seconds)*256
          Hence a 1 second maximum and a 3.9 millisecond minimum sound duration.
          After the sound length has be changed, the sound channel must be
          resetted via bit F of <A HREF="#REG_SOUNDCNT_X">REG_SOUND3CNT_X</A>. 

D-F <FONT COLOR="#9900CC">(R)</FONT> = Output volume ratio:
          
          000 - Mute
          001 - 100%
          100 - 75%
          010 - 50%
          011 - 25%</PRE>
<P><BR>
<B>Address: 0x04000074 - <A NAME="REG_SOUND3CNT_X"></A>REG_SOUND3CNT_X (Sound 3 Frequency, reset and loop control)(Unimplemented
in CowBite)</B></P>
<PRE><FONT COLOR="#CC9900">W</FONT>          <FONT COLOR="#CC9900">W W W  W W W W  W W W W</FONT>
F E D C  B A 9 8  7 6 5 4  3 2 1 0 
<FONT COLOR="#0099FF">R</FONT> <FONT COLOR="#9900CC">T</FONT> <FONT COLOR="#BBBBBB">X X  X</FONT> <FONT COLOR="#FF0099">F F F  F F F F  F F F F</FONT></PRE>
<PRE>0-A <FONT COLOR="#FF0099">(F)</FONT> = Sound frequency. The minimum frequency is 64Hz and the maximum is
          131Khz. Can be calculated from the following formula:
          F(hz)=4194304/(32*(2048-register value)).

E <FONT COLOR="#9900CC">(T)</FONT> = Timed sound. When set to 0, sound 3 is played continuously regardless of
        the length data in <A HREF="#REG_SOUND3CNT_H">REG_SOUND3CNT_H</A>. When set to 1, sound is played for
        that specified length and after that, bit 2 of <A HREF="#REG_SOUNDCNT_X">REG_SOUNDCNT_X</A> is reset.

F <FONT COLOR="#0099FF">(R)</FONT> = Sound reset. When set, sound resets and restarts at the specified
        frequency. Frequency and sound reset must be perfomed in a single write
        since both are write only. In continuous mode, frequency can be changed
        without resetting the sound channel.</PRE>
<P><BR>
<B><BR>
Address: 0x04000078 - <A NAME="REG_SOUND4CNT_L"></A>REG_SOUND4CNT_L (Sound 4 Length, output level and envelope
control)(Unimplemented in CowBite)</B></P>
<PRE>                     <FONT COLOR="#CC9900">W W  W W W W</FONT>
F E D C  B A 9 8  7 6 5 4  3 2 1 0 
<FONT COLOR="#008800">I I I I</FONT><FONT COLOR="#0099FF">  M</FONT> <FONT COLOR="#9900CC">T T T</FONT><FONT COLOR="#BBBBBB">  X X </FONT><FONT
COLOR="#FF0099">L L  L L L L</FONT>

</PRE>
<PRE>0-5 <FONT COLOR="#FF0099">(L)</FONT> = Sound length. This is a 6 bit value obtained from the following formula:
          Sound length= (64-register value)*(1/256) seconds. After the sound length
          has been changed, the sound channel must be resetted via bit F of
          <A HREF="#REG_SOUND4CNT_H">REG_SOUND4CNT_H</A> (when using timed mode). 
8-A <FONT COLOR="#9900CC">(T)</FONT> = Envelope step time. This is the delay between successive envelope
          increase or decrease. It is given by the following formula: 
          Time=register value*(1/64) seconds. 
B   <FONT COLOR="#0099FF">(M)</FONT> = Envelope mode. Controls if the envelope is to increase or decrease in volume
          over time.

          0 - Envelope decreases
          1 - Envelope increases</PRE>
<PRE>D-F <FONT COLOR="#008800">(I)</FONT> = Initial Envelope value<B>. </B>1111 produces the maximum volume and 0000 mutes
          the sound. </PRE>
<P><B><BR>
<BR>
Address: 0x0400007C - <A NAME="REG_SOUND4CNT_H"></A>REG_SOUND4CNT_H (Sound 4 Noise parameters, reset and loop control)(Unimplemented
in CowBite)</B></P>
<PRE><FONT COLOR="#CC9900">W</FONT><B>
</B>F E D C  B A 9 8  7 6 5 4  3 2 1 0 
<FONT COLOR="#FF3300">R</FONT> <FONT COLOR="#008800">T</FONT> <FONT COLOR="#BBBBBB">X X  X X X X</FONT> <FONT COLOR="#0099FF"> P P P P</FONT>  <FONT
COLOR="#9900CC">S</FONT> <FONT COLOR="#FF0099">C C C</FONT>

</PRE>
<PRE>0-2 <FONT COLOR="#FF0099">(C)</FONT> = Clock divider frequency. This divides the CPU frequency. Its output is
          then fed into the counter's pre-scaler (controlled by bits 4-7) which
          further devides the frequency.

          000: f*2      f=4.194304 Mhz/8
          001: f
          010: f/2
          011: f/3
          100: f/4
          101: f/5
          110: f/6
          111: f/7</PRE>
<PRE>3 <FONT COLOR="#9900CC">  (S)</FONT> = Counter stages: 0=15 stages, 1=7 stages. This controls the period of the
          polynomial counter. It is given by (2^n)-1 where n is the number of
          stages. So for n=7, the pseudo-noise period lasts 63 input clocks.
          After that, the counter restarts the same count sequence. 
4-7 <FONT COLOR="#0099FF">(P)</FONT> = Counter Pre-Stepper frequency:
          
          0000: Q/2
          0001: Q/2^2
          0010: Q/2^3
          0011: Q/2^4
          ....
          1101: Q/2^14
          1110: Not used
          1111: Not used   
          Where Q is the clock divider's output frequency</PRE>
<PRE>E   <FONT COLOR="#008800">(T)</FONT> = Timed sound. When set to 0, sound 4 is played continuously regardless of
          the length data in <A HREF="#REG_SOUND4CNT_L">REG_SOUND4CNT_L</A>. When set to 1, sound is played for that
          specified length and after that, bit 3 of <A HREF="#REG_SOUNDCNT_X">REG_SOUNDCNT_X</A> is reset.
F <FONT COLOR="#FF3300">  (R)</FONT> = Sound reset. When bit F is set to 1, Envelope is set to initial value,
          the LFSR count sequence is resetted and the sound restarts.<B> </B>In continuous
          mode, all parameters can be changed but the sound needs to be resetted when
          modifying the envelope initial volume or the clock divider for changes to
          take effects. </PRE>
<P><B><BR>
</B>Channel 4 produces pseudo-noise generated by a polynomial counter. It is based on a 7/15 stages linear-feedback
shift register (LFSR). LFSR counts in a pseudo-random order where each state is generated once and only once during
the whole count sequence. The sound is produced by the least significant bit's output stage. <B><BR>
<BR>
<BR>
Address: 0x04000080 - <A NAME="REG_SOUNDCNT_L"></A>REG_SOUNDCNT_L (Sound 1-4 Output level and Stereo control)(Unimplemented
in CowBite)</B></P>
<PRE>                           <FONT COLOR="#FF0000">?</FONT>
F E D C  B A 9 8  7 6 5 4  3 2 1 0 
<FONT COLOR="#9900CC">R</FONT> <FONT COLOR="#FF0099">Q</FONT> <FONT COLOR="#FF3300">P</FONT> <FONT COLOR="#008800">O</FONT> <FONT
COLOR="#0099FF"> N</FONT> <FONT COLOR="#9900CC">M</FONT> <FONT COLOR="#FF0099">L</FONT> <FONT COLOR="#FF3300">K</FONT> <FONT
COLOR="#008800"> J</FONT> <FONT COLOR="#0099FF">I I I</FONT> <FONT COLOR="#9900CC"> H</FONT> <FONT COLOR="#FF0099">G G G</FONT>
</PRE>
<PRE>0-2 <FONT COLOR="#FF0099">(G)</FONT> = DMG Left Volume
3   <FONT COLOR="#9900CC">(H)</FONT> = Vin Left on/off (?) - According to BeLogic, Vin on/off allowed the
          original GameBoy paks to provide their own sound source. It is unkown
          whether they still work on a GBA.
4-6 <FONT COLOR="#0099FF">(I)</FONT> = DMG Right Volume
7 <FONT COLOR="#008800">  (J)</FONT> = Vin Right on/off (?) 
8 <FONT COLOR="#FF3300">  (K)</FONT> = DMG Sound 1 to left output
9 <FONT COLOR="#FF0099">  (L)</FONT> = DMG Sound 2 to left output
A <FONT COLOR="#9900CC">  (M)</FONT> = DMG Sound 3 to left output 
B <FONT COLOR="#0099FF">  (N)</FONT> = DMG Sound 4 to left output
C <FONT COLOR="#008800">  (O)</FONT> = DMG Sound 1 to right output
D <FONT COLOR="#FF3300">  (P)</FONT> = DMG Sound 2 to right output
E <FONT COLOR="#FF33CC">  (Q)</FONT> = DMG Sound 3 to right output
F <FONT COLOR="#9933FF">  (R)</FONT> = DMG Sound 4 to right output </PRE>
<P><BR>
This register controls only the DMG output amplifiers and have no effects on the individual sound channels' processing,
or Direct Sound channels' volume.<B><BR>
<BR>
<BR>
Address: 0x04000082 - <A NAME="REG_SOUNDCNT_H"></A>REG_SOUNDCNT_H (Direct Sound control and Sound 1-4 output ratio)(Implemented
in CowBite)</B></P>
<PRE><FONT COLOR="#CC9900">W        W</FONT>        
F E D C  B A 9 8  7 6 5 4  3 2 1 0 
<FONT COLOR="#FF0099">Q</FONT><FONT COLOR="#FF3300"> P</FONT> <FONT COLOR="#008800">O</FONT> <FONT COLOR="#0099FF">N</FONT>  <FONT
COLOR="#9900CC">M </FONT><FONT COLOR="#FF0099">L</FONT> <FONT COLOR="#FF3300">K</FONT> <FONT COLOR="#008800">J</FONT> <FONT
COLOR="#BBBBBB"> X X X X</FONT> <FONT COLOR="#0099FF"> I</FONT> <FONT COLOR="#9900CC">H</FONT> <FONT COLOR="#FF0099">G G</FONT></PRE>
<PRE>0-1 <FONT COLOR="#FF0099">(G)</FONT> = Output Sound Ratio for channels 1-4.

          00 - 25%
          01 - 50%
          10 - 100%
          11 - ??

2 <FONT COLOR="#9900CC">  (H)</FONT> = Direct sound A output ratio (0 - 50%, 1 - 100%)
3 <FONT COLOR="#0099FF">  (I)</FONT> = Direct sound B output ratio (0 - 50%, 1 - 100%)
8 <FONT COLOR="#008800">  (J)</FONT> = Direct Sound A to right output
9 <FONT COLOR="#FF3300">  (K)</FONT> = Direct sound A to left output 
A <FONT COLOR="#FF0099">  (L)</FONT> = Direct sound A Sampling rate timer (<A HREF="#REG_TM0DAT">timer 0</A> or <A
HREF="#REG_TM1DAT">1</A>). Use this to set which
          timer contorls the playback frequency.
B <FONT COLOR="#9900CC">  (M)</FONT> = Direct sound <A HREF="#REG_FIFO_A_L">A FIFO</A> reset 
C <FONT COLOR="#0099FF">  (N)</FONT> = Direct sound B to right output 
D <FONT COLOR="#008800">  (O)</FONT> = Direct sound B to left output 
E <FONT COLOR="#FF3300">  (P)</FONT> = Direct sound B Sampling rate timer (<A HREF="#REG_TM0DAT">timer 0</A> or <A
HREF="#REG_TM1DAT">1</A>). Use this to set
          which timer controls the playback frequency.
F <FONT COLOR="#FF0099">  (Q)</FONT> = Direct sound <A HREF="#REG_FIFO_B_L">B FIFO</A> reset </PRE>
<P><BR>
This register is used in controlling Direct Sound on the GBA. Output ratios control the volume, in percentage,
that gets output to the speakers.<BR>
<BR>
<B><BR>
Address: 0x04000084 - <A NAME="REG_SOUNDCNT_X"></A>REG_SOUNDCNT_X (Master sound enable and Sound 1-4 play status)(Partially
Implemented in CowBite)</B></P>
<PRE><FONT COLOR="#FF0000">                           R R R R</FONT>
F E D C  B A 9 8  7 6 5 4  3 2 1 0 
<FONT COLOR="#BBBBBB">X X X X  X X X X</FONT> <FONT COLOR="#FF3300"> N</FONT> <FONT COLOR="#BBBBBB">X X X</FONT>  <FONT
COLOR="#008800">J</FONT> <FONT COLOR="#0099FF">I</FONT> <FONT COLOR="#9900CC">H</FONT> <FONT COLOR="#FF0099">G</FONT>
</PRE>
<PRE>0 <FONT COLOR="#FF0099">(G)</FONT> = DMG Sound 1 Status (Read only). 0 - Stopped, 1 - Playing
1 <FONT COLOR="#9900CC">(H)</FONT> = DMG Sound 2 Status (Read only). 0 - Stopped, 1 - Playing
2 <FONT COLOR="#0099FF">(I)</FONT> = DMG Sound 3 Status (Read only). 0 - Stopped, 1 - Playing
3 <FONT COLOR="#008800">(J)</FONT> = DMG Sound 4 Status (Read only). 0 - Stopped, 1 - Playing
7 <FONT COLOR="#FF3300">(N)</FONT> = All Sound circuit enable</PRE>
<P><BR>
This register is used to monitor the play status of sounds and to turn on or off all sound circuits. Turning the
sound circuits off saves battery power, allowing them to last up to 10% longer.<BR>
<B><BR>
<BR>
Address: 0x04000088 - <A NAME="REG_SOUNDBIAS"></A>REG_SOUNDBIAS (Sound bias and Amplitude resolution control)(Unimplemented
in CowBite)</B></P>
<PRE>F E D C  B A 9 8  7 6 5 4  3 2 1 0 
<FONT COLOR="#9900CC">R R</FONT> <FONT COLOR="#BBBBBB">X X  X X</FONT> <FONT COLOR="#FF0099">B B  B B B B  B B B</FONT><FONT
COLOR="#BBBBBB"> X</FONT></PRE>
<PRE>1-9 <FONT COLOR="#FF0099">(B)</FONT> = PWM bias value, controlled by the BIOS.<B>
</B>E-F <FONT COLOR="#9900CC">(R)</FONT> = Amplitude resolutions
          00 - 9 bit at 32768 hz
          01 - 8 bit at 65536 hz
          10 - 7 bit at 131072 hz
          11 - 6 bit at 262144 hz</PRE>
<P>The BIAS setting is used to offset the sound output and bring it back into a signed range. When the BIOS starts
up, it runs a timing loop where it slowly raises the BIAS voltage from 0 to 512. This setting should not be changed.
At best, the sound will become distorted. At worst the amplifier inside the GBA could be damaged. <BR>
<BR>
When accessing bits F-E, a read-modify-write is required. The default value for bits F-E is 00. Most if not all
games use 01 for this setting.<BR>
<B><BR>
<BR>
Address: 0x04000090 - <A NAME="REG_WAVE_RAM0_L"></A>REG_WAVE_RAM0_L (Sound 3 samples 0-3)<BR>
Address: 0x04000092 - <A NAME="REG_WAVE_RAM0_H"></A>REG_WAVE_RAM0_H (Sound 3 samples 4-7)<BR>
Address: 0x04000094 - <A NAME="REG_WAVE_RAM1_L"></A>REG_WAVE_RAM1_L (Sound 3 samples 8-11)<BR>
Address: 0x04000096 - <A NAME="REG_WAVE_RAM1_H"></A>REG_WAVE_RAM1_H (Sound 3 samples 12-15)<BR>
Address: 0x04000098 - <A NAME="REG_WAVE_RAM2_L"></A>REG_WAVE_RAM2_L (Sound 3 samples 16-19)<BR>
Address: 0x0400009A - <A NAME="REG_WAVE_RAM2_H"></A>REG_WAVE_RAM2_H (Sound 3 samples 20-23)<BR>
Address: 0x0400009C - <A NAME="REG_WAVE_RAM3_L"></A>REG_WAVE_RAM3_L (Sound 3 samples 23-27)<BR>
Address: 0x0400009E - <A NAME="REG_WAVE_RAM3_H"></A>REG_WAVE_RAM3_H (Sound 3 samples 28-31)<BR>
<BR>
</B>These registers together contain four (4 bytes each) 4-bit wave RAM samples for Sound channel 3.<B><BR>
<BR>
<BR>
Address: 0x040000A0 - <A NAME="REG_FIFO_A_L"></A>REG_FIFO_A_L (Direct Sound channel A samples 0-1)(Write Only)<BR>
Address: 0x040000A2 - <A NAME="REG_FIFO_A_H"></A>REG_FIFO_A_H (Direct Sound channel A samples 2-3)(Write Only)<BR>
Address: 0x040000A4 - <A NAME="REG_FIFO_B_L"></A>REG_FIFO_B_L (Direct Sound channel B samples 0-1)(Write Only)<BR>
Address: 0x040000A6 - <A NAME="REG_FIFO_B_H"></A>REG_FIFO_B_H (Direct Sound channel B samples 2-3)(Write Only)</B><BR>
<BR>
These are the locations of the Direct Sound 8-bit FIFO samples, from which Direct Sound pulls the music data to
be played on the speakers. Note that there are only 8 bytes total for all your samples. You repeatedly fill these
from a buffer of your own using <A HREF="#REG_DMA0CNT">DMA0</A> or <A HREF="#REG_DMA1CNT">DMA1</A>, or by using
timer <A HREF="#Hardware Interrupts">interrupts</A>. <BR>
<BR>
To fill them using DMA, first set <A HREF="#REG_TM0DAT">Timer 0</A> or <A HREF="#REG_TM1DAT">Timer 1</A> to refresh
at the appropriate sample rate (for example, 16khz). Next, set the <A HREF="#REG_DMA0SAD">DMA source address</A>
to a sound sample in memory, and the <A HREF="#REG_DMA0DST">destination address</A> to one of these FIFO registers.
Use <A HREF="#REG_SOUNDCNT_H">REG_SOUNTCNT_H</A> to reset FIFO and tell Direct Sound to get its sampling rate from
Timer 0 or Timer 1. Finally, set the <A HREF="#REG_DMA0CNT">DMA control register</A> to start on FIFO empty (start
mode 11) and to repeat, then enable the timers. All of this will cause the hardware to play sound samples in FIFO
at the rate specified in your timer, and automatically refill them using DMA.<BR>
<BR>
To fill these using <A HREF="#Hardware Interrupts">interrupts</A>, follow a similar process, but instead of using
DMA, set the clock to interrupt on overflow. When using interrupts instead of DMA, BeLogic recommends setting the
<A HREF="#REG_TM0CNT">timer</A> divider to 1024 and start the timer at 0xFFFF order to get a sampling rate of 16.384
khz. This apparently causes less distortion than if you simply set the start time of the clock to 0xFFFF - (2^24/16000).<BR>
<BR>
Note that reading from these registers can yield unpredictable results. It might be interesting to see just <I>how</I>
unpredictable...<BR>
<BR>

<HR ALIGN="CENTER">

<H3><B>Addresses: 0x40000B0, 0x40000BC, 0x40000C8, 0x40000D4 (<A NAME="DMA Source Registers"></A>DMA Source Registers)(Write
Only)</B></H3>
<P><B>Address: 0x40000B0 - <A NAME="REG_DMA0SAD"></A>REG_DMA0SAD (DMA0 Source Address)</B>(Write Only)</P>
<PRE>31 30 29 28  27 26 25 24  23 22 21 20  19 18 17 16  15 14 13 12  11 10 9 8  7 6 5 4  3 2 1 0
<FONT COLOR="#BBBBBB">X  X  X  X   X</FONT>  <FONT COLOR="#FF0099">A  A  A   A  A  A  A   A  A  A  A   A  A  A  A   A  A  A A  A A A A  A A A A</FONT><B>

</B>0-26 <FONT COLOR="#FF0099">(A)</FONT> = 27-bit source address</PRE>
<P>This is the source address for DMA channel 0 transfers. Note that it is 27-bit.<B><BR>
<BR>
Address: 0x40000BC - <A NAME="REG_DMA1SAD"></A>REG_DMA1SAD (DMA1 Source Address)<BR>
Address: 0x40000C8 - <A NAME="REG_DMA2SAD"></A>REG_DMA2SAD (DMA2 Source Address)<BR>
Address: 0x40000D4 - <A NAME="REG_DMA3SAD"></A>REG_DMA3SAD (DMA3 Source Address)</B></P>
<PRE>31 30 29 28  27 26 25 24  23 22 21 20  19 18 17 16  15 14 13 12  11 10 9 8  7 6 5 4  3 2 1 0
<FONT COLOR="#BBBBBB">X  X  X  X  </FONT><FONT COLOR="#FF0099"> A  A  A  A   A  A  A  A   A  A  A  A   A  A  A  A   A  A  A A  A A A A  A A A A<B>
</B></FONT><B>
</B>0-27 <FONT COLOR="#FF0099">(A)</FONT> = 28-bit source address</PRE>
<P>This is the source address for DMA channel 1, 2, or 3 transfers. Note that it is 28-bit.
<H3><B><BR>
Addresses: 0x40000B4, 0x40000C0, 0x40000CC, 0x40000D8 (<A NAME="DMA Destination Registers"></A>DMA Destination
Registers</B>) (Write Only)</H3>
<P><B>Address: 0x40000B4 - <A NAME="REG_DMA0DST"></A>REG_DMA0DAD (DMA0 Destination Address)<BR>
Address: 0x40000C0 -<A NAME="REG_DMA1DST"></A> REG_DMA1DAD (DMA1 Destination Address) <BR>
Address: 0x40000CC - <A NAME="REG_DMA2DST"></A>REG_DMA2DAD (DMA2 Destination Address)</B></P>
<PRE>31 30 29 28  27 26 25 24  23 22 21 20  19 18 17 16  15 14 13 12  11 10 9 8  7 6 5 4  3 2 1 0
<FONT COLOR="#BBBBBB">X  X  X  X   X  </FONT><FONT COLOR="#FF0099">A  A  A   A  A  A  A   A  A  A  A   A  A  A  A   A  A  A A  A A A A  A A A A</FONT><B>

</B>0-27 <FONT COLOR="#FF0099">(A)</FONT> = 27-bit destination address</PRE>
<P>This is the dest address for DMA channel 0, 1, and 2 transfers. Note that it is 27-bit.<BR>
<BR>
<BR>
<B>Address: 0x40000D8 - <A NAME="REG_DMA3DST"></A>REG_DMA3DAD (DMA3 Destination Address)(Write Only)</B></P>
<PRE>31 30 29 28  27 26 25 24  23 22 21 20  19 18 17 16  15 14 13 12  11 10 9 8  7 6 5 4  3 2 1 0
<FONT COLOR="#BBBBBB">X  X  X  X  </FONT><FONT COLOR="#FF0099"> A  A  A  A   A  A  A  A   A  A  A  A   A  A  A  A   A  A  A A  A A A A  A A A A</FONT><B>

</B>0-27 <FONT COLOR="#FF0099">(A)</FONT> = 28-bit destination address</PRE>
<P>This is the dest address for DMA channel 3 transfers. Note that it is 28-bit.
<H3><B><BR>
Addresses: 0x40000B8, 0x40000C4, 0x40000D0, 0x40000DC (<A NAME="DMA Count Registers"></A>DMA Count Registers)</B>(Write
Only)</H3>
<P><B>Address: 0x40000B8 - <A NAME="REG_DMA0SIZE"></A>REG_DMA0CNT_L (DMA0 Count Register)<BR>
Address: 0x40000C4 - <A NAME="REG_DMA1SIZE"></A>REG_DMA1CNT_L (DMA1 Count Register)<BR>
Address: 0x40000D0 - <A NAME="REG_DMA2SIZE"></A>REG_DMA2CNT_L (DMA2 Count Register)<BR>
Address: 0x40000DC - <A NAME="REG_DMA3SIZE"></A>REG_DMA3CNT_L (DMA3 Count Register)</B></P>
<PRE>F E D C  B A 9 8  7 6 5 4  3 2 1 0 
<FONT COLOR="#BBBBBB">X X</FONT> <FONT COLOR="#FF0099">L L  L L L L  L L L L  L L L L</FONT> </PRE>
<PRE>0-D <FONT COLOR="#FF0099">(L)</FONT> = Number of words or halfwords to copy</PRE>
<P><BR>
(Note: In some places you will see the <A HREF="#DMA Control Registers">DMA control</A> and DMA count registers
depicted as a single 32-bit register called REG_DMAXCNT. I opted to treat them as two 16-bit registers for sake
of clarity.)
<H3><B>Addresses: 0x40000BA, 0x40000C6, 0x40000D2, 0x40000DE (<A NAME="DMA Control Registers"></A>DMA Control Registers)</B></H3>
<P><B>Address: 0x40000BA - <A NAME="REG_DMA0CNT"></A>REG_DMA0CNT_H (DMA0 Control Register) <BR>
Address: 0x40000C6 -<A NAME="REG_DMA1CNT"></A>REG_DMA1CNT_H (DMA1 Control Register) <BR>
Address: 0x40000D2 - <A NAME="REG_DMA2CNT"></A>REG_DMA2CNT_H (DMA2 Control Register) <BR>
Address: 0x40000DE - <A NAME="REG_DMA3CNT"></A>REG_DMA3CNT_H (DMA3 Control Register)</B></P>
<PRE><FONT COLOR="#FF0000">         ?             </FONT>
F E D C  B A 9 8  7 6 5 4  3 2 1 0 
<FONT COLOR="#0099FF">N </FONT><FONT COLOR="#9900CC">I </FONT><FONT COLOR="#FF0099">M M </FONT><FONT COLOR="#FF3300"> U</FONT> <FONT
COLOR="#008800">S</FONT> <FONT COLOR="#0099FF">R</FONT> <FONT COLOR="#9900CC">A  A</FONT> <FONT COLOR="#FF0099">B B</FONT> <FONT
COLOR="#BBBBBB">X  X X X X</FONT> 

</PRE>
<PRE>(Note: In some places you will see the DMA control and <A HREF="#DMA Count Registers">DMA count</A> registers
depicted as a single 32-bit register called REG_DMAXCNT. I opted to treat
them as two 16-bit registers for sake of clarity.)

5-6 <FONT COLOR="#FF0099">(B)</FONT> = Type of increment applied to destination address. If enabled, the
          address will be incremented/decremented by 2 or 4 bytes, depending on
          the selected size. When the DMA is activated, the contents of these
          registers are copied to internal counters in the DMA hardware, which
          then increments/decrements these registers during transfer, preserving
          the contents of the IORAM registers.<A HREF="#DMANote">*</A>

          00: Increment after each copy 
          01: Decrement after each copy 
          10: Leave unchanged 
          11: Increment without after each copy, reset to initial value at the
              end of transfer (or at the end of the current repetition)

7-8 <FONT COLOR="#9900CC">(A)</FONT> = Type of increment applied to source address:
          00: Increment after each copy
          01: Decrement after each copy 
          10: Leave unchanged 
          11: Illegal

          Note: I am somewhat uncertain about option &quot;11&quot; for both of these.
          Can anyone confirm? 

9   <FONT COLOR="#0099FF">(R)</FONT> = Repeat. When in start modes 1 or 2, this bit causes the transfer to
          repeat for each interval. 
A <FONT COLOR="#008800">  (S)</FONT> = Size. If set, copy 32-bit quantities (words) If clear, copy 16-bit
          quantities (half words) 
B <FONT COLOR="#FF3300">  (U)</FONT> = Unknown.  For DMA 0, 1, and 2, this bit is read only and set to 0. However,
          for DMA 3, it appears to be writeable. Thoughts, anyone?
C-D <FONT COLOR="#FF0099">(M)</FONT> = Start Mode.
          
          00: Transfer immediately 
          01: Transfer on vblank (i.e. vdma)
          10: Transfer on hblank (i.e. hdma.  Note that, unlike h-interrupts,
                                  hdma does NOT occur during vblank.)
          11: The function of this varies based on the DMA channel.

              For DMA 1 or 2: Instructs the DMA to repeat on FIFO-empty requests.
              When this is set the size and count are ignored and a single 32 bit
              quantity is transferred on FIFO empty.
              For DMA 3: Apparently allows transfers to start at the beginning of a
              rendering line, copying data into a buffer as the line is being drawn
              on the screen. Useful for flicker-free transfers in mode 3, which has
              no backbuffer.

E <FONT COLOR="#9900CC">  (I)</FONT> = IRQ. Setting this bit causes the DMA to generate an <A HREF="#Hardware Interrupts">interrupt</A> when it is
          done with the data transfer.
F <FONT COLOR="#0099FF">  (N)</FONT> = Set this bit to enable DMA operation. Clear to end DMA operation.</PRE>
<P><BR>
This address controls a DMA transfer which allows large amounts of data to be transferred from one area of memory
to another. It is theoretically twice as fast as transfering by the CPU, which uses at least one cycle for a read
instruction and another for a write. DMA can also be used to clear memory to a constant value, if the source address
is not incremented with each copy. Fist, set the <A HREF="#DMA Source Registers">DMASAD</A> and <A HREF="#DMA Destination Registers">DMADAD</A>
registers to point to the addresses you want. Writing to DMACNT_H address with a '1' in the N field and a '00'
in the M field will start the transfer immediately. <BR>
<BR>
DMA transfers may occur on an interrupt if the start mode bits are set for this. DMAs have a priority ranking with
3 at the lowest and 0 at the highest. For most cases, program code will be using DMA3 as it is lowest priority,
allowing it to be interrupted by more important DMA (see below).<BR>
<BR>
Specific DMAs have the following properties:<BR>
<BR>
<A NAME="DMA0"></A><B>DMA0</B>: This DMA is the highester priority, but cannot be used to access cartridge memory
(addresses 0x8000000 and higher). It is suitable for time-critical operations such as transfering scale and rotate
data to the background scaling registers. Since it takes precedence over other DMAs, it will not be postponed or
interrupted (possibly causing undesirable results such as screen artifacts).<BR>
<BR>
<A NAME="DMA1"></A><B>DMA1</B> and <A NAME="DMA2"></A><B>DMA2</B>: These are the only DMA that can be used for
sound FIFO. If start mode &quot;11&quot; is set, the DMA will be triggered on FIFO empty. I believe that FIFO A
always sends its empty requests to DMA1 and that FIFO B sends its empty requests only to DMA2, though I don't have
any verification of this.<BR>
<BR>
<A NAME="DMA3"></A><B>DMA3</B>: This is is the lowest priority and thus often used as a &quot;general purpose&quot;
DMA. Using this DMA for your basic memory transfers ensures that sound FIFO DMA and other time-critical DMA are
not delayed, making audio or visual artifacts less likely.<BR>
<BR>
<A NAME="DMANote"></A>* (Originally I had assumed a direct mapping between the source/destination registers and
the current transfer address, and thus this section of the doc distinguished between transfers which wrote-back
to the registers and those which did not. This appears to have been an incorrect assumption, and was brought to
light as I delved further into sound emulation)
<H3><BR>
DMA Transfer Ratings</H3>
<P><BR>
The following table lists the cycle timings for various DMA transfers. The format of each entry is :</P>
<PRE><FONT COLOR="#CC9900">16 bit DMA</FONT> / <FONT COLOR="#CC3300">32 bit DMA</FONT></PRE>
<P>Units are in <I>cycles per item transfered</I>. Thus, a rating of <FONT COLOR="#CC9900">4</FONT>/<FONT COLOR="#CC3300">8</FONT>
indicates that the transfer takes 4 cycles for every 16 bits transferred with 16 bit DMA, or 8 cycles for every
32 bits transfered with 32 bit DMA.</P>
<PRE><B>Source       Destination</B>
             EWRAM    IWRAM    IO       PAL RAM  VRAM     OAM
ROM 0 WS     <FONT COLOR="#CC9900">4</FONT>/<FONT COLOR="#CC3300">8</FONT>      <FONT COLOR="#CC9900">2</FONT>/<FONT
COLOR="#CC3300">3</FONT>      <FONT COLOR="#CC9900">2</FONT>/<FONT COLOR="#CC3300">3</FONT>      <FONT COLOR="#CC9900">2</FONT>/<FONT
COLOR="#CC3300">4</FONT>      <FONT COLOR="#CC9900">2</FONT>/<FONT COLOR="#CC3300">4</FONT>      <FONT COLOR="#CC9900">2</FONT>/<FONT
COLOR="#CC3300">3</FONT>
ROM 1 WS     <FONT COLOR="#CC9900">5</FONT>/<FONT COLOR="#CC3300">10</FONT>     <FONT COLOR="#CC9900">3</FONT>/<FONT
COLOR="#CC3300">5</FONT>      <FONT COLOR="#CC9900">3</FONT>/<FONT COLOR="#CC3300">5</FONT>      <FONT COLOR="#CC9900">3</FONT>/<FONT
COLOR="#CC3300">6</FONT>      <FONT COLOR="#CC9900">3</FONT>/<FONT COLOR="#CC3300">6</FONT>      <FONT COLOR="#CC9900">3</FONT>/<FONT
COLOR="#CC3300">5</FONT>
ROM 2 WS     <FONT COLOR="#CC9900">6</FONT>/<FONT COLOR="#CC3300">12</FONT>     <FONT COLOR="#CC9900">4</FONT>/<FONT
COLOR="#CC3300">7</FONT>      <FONT COLOR="#CC9900">4</FONT>/<FONT COLOR="#CC3300">7</FONT>      <FONT COLOR="#CC9900">4</FONT>/<FONT
COLOR="#CC3300">8</FONT>      <FONT COLOR="#CC9900">4</FONT>/<FONT COLOR="#CC3300">8</FONT>      <FONT COLOR="#CC9900">4</FONT>/<FONT
COLOR="#CC3300">7</FONT>
EWRAM        <FONT COLOR="#CC9900">6</FONT>/<FONT COLOR="#CC3300">12</FONT>     <FONT COLOR="#CC9900">4</FONT>/<FONT
COLOR="#CC3300">7</FONT>      <FONT COLOR="#CC9900">4</FONT>/<FONT COLOR="#CC3300">7</FONT>      <FONT COLOR="#CC9900">4</FONT>/<FONT
COLOR="#CC3300">8</FONT>      <FONT COLOR="#CC9900">4</FONT>/<FONT COLOR="#CC3300">8</FONT>      <FONT COLOR="#CC9900">4</FONT>/<FONT
COLOR="#CC3300">7</FONT>
IWRAM        <FONT COLOR="#CC9900">4</FONT>/<FONT COLOR="#CC3300">7</FONT>      <FONT COLOR="#CC9900">2</FONT>/<FONT
COLOR="#CC3300">2</FONT>      <FONT COLOR="#CC9900">2</FONT>/<FONT COLOR="#CC3300">2</FONT>      <FONT COLOR="#CC9900">2</FONT>/<FONT
COLOR="#CC3300">3</FONT>      <FONT COLOR="#CC9900">2</FONT>/<FONT COLOR="#CC3300">3</FONT>      <FONT COLOR="#CC9900">2</FONT>/<FONT
COLOR="#CC3300">2</FONT>
I/O          <FONT COLOR="#CC9900">4</FONT>/<FONT COLOR="#CC3300">7</FONT>      <FONT COLOR="#CC9900">2</FONT>/<FONT
COLOR="#CC3300">2</FONT>      <FONT COLOR="#CC9900">2</FONT>/<FONT COLOR="#CC3300">2</FONT>      <FONT COLOR="#CC9900">2</FONT>/<FONT
COLOR="#CC3300">3</FONT>      <FONT COLOR="#CC9900">2</FONT>/<FONT COLOR="#CC3300">3</FONT>      <FONT COLOR="#CC9900">2</FONT>/<FONT
COLOR="#CC3300">2</FONT>
PAL RAM      <FONT COLOR="#CC9900">4</FONT>/<FONT COLOR="#CC3300">8</FONT>      <FONT COLOR="#CC9900">2</FONT>/<FONT
COLOR="#CC3300">2</FONT>      <FONT COLOR="#CC9900">2</FONT>/<FONT COLOR="#CC3300">3</FONT>      <FONT COLOR="#CC9900">2</FONT>/<FONT
COLOR="#CC3300">4</FONT>      <FONT COLOR="#CC9900">2</FONT>/<FONT COLOR="#CC3300">4</FONT>      <FONT COLOR="#CC9900">2</FONT>/<FONT
COLOR="#CC3300">2</FONT>
VRAM         <FONT COLOR="#CC9900">4</FONT>/<FONT COLOR="#CC3300">8</FONT>      <FONT COLOR="#CC9900">2</FONT>/<FONT
COLOR="#CC3300">3</FONT>      <FONT COLOR="#CC9900">2</FONT>/<FONT COLOR="#CC3300">3</FONT>      <FONT COLOR="#CC9900">2</FONT>/<FONT
COLOR="#CC3300">4</FONT>      <FONT COLOR="#CC9900">2</FONT>/<FONT COLOR="#CC3300">4</FONT>      <FONT COLOR="#CC9900">2</FONT>/<FONT
COLOR="#CC3300">2</FONT>
OAM          <FONT COLOR="#CC9900">4</FONT>/<FONT COLOR="#CC3300">7</FONT>      <FONT COLOR="#CC9900">2</FONT>/<FONT
COLOR="#CC3300">2</FONT>      <FONT COLOR="#CC9900">2</FONT>/<FONT COLOR="#CC3300">2</FONT>      <FONT COLOR="#CC9900">2</FONT>/<FONT
COLOR="#CC3300">3</FONT>      <FONT COLOR="#CC9900">2</FONT>/<FONT COLOR="#CC3300">3</FONT>      <FONT COLOR="#CC9900">2</FONT>/<FONT
COLOR="#CC3300">2</FONT>
</PRE>
<P>Note that it is not possible to DMA transfer from or to SRAM (Cart RAM) or BIOS, and (obviously) it is not possible
to transfer to ROM.<BR>
<BR>
Thanks to Kay for supplying these transfer statistics!!
<H3><BR>

<HR ALIGN="CENTER">
<BR>
Addresses: 0x4000100 - 0x400010E (<A NAME="Timer registers"></A>Timer registers)</H3>
<P><B>Address: 0x4000100 - <A NAME="REG_TM0DAT"></A>REG_TM0D (Timer 0 Data)<BR>
Address: 0x4000104 - <A NAME="REG_TM1DAT"></A>REG_TM1D (Timer 1 Data)<BR>
Address: 0x4000108 - <A NAME="REG_TM2DAT"></A>REG_TM2D (Timer 2 Data)<BR>
Address: 0x400010C - <A NAME="REG_TM3DAT"></A>REG_TM3D (Timer 3 Data)</B></P>
<PRE>F E D C  B A 9 8  7 6 5 4  3 2 1 0 
<FONT COLOR="#FF0099">D D D D  D D D D  D D D D  D D D D</FONT></PRE>
<PRE>0-F <FONT COLOR="#FF0099">(D)</FONT> = Current count of the timer.</PRE>
<P><BR>
Note that these registers are R/W. The default is to start counting from 0x0000, but if a value is written to this
register, the timer will henceforth use that as a starting value. Thus the rate at which timers overflow and generate
<A HREF="#Hardware Interrupts">interrupts</A> (see <A HREF="#REG_TM0CNT">REG_TMXCNT</A>, below) can be customized.<B><BR>
<BR>
</B>Timer 0 and Timer 1 are used to control the rate of Direct Sound FIFO. When using <A HREF="#REG_DMA0CNT">DMA</A>
with start mode 11, they can automatically cause it to refill the FIFO. To set the rate of playback in hz, write
the value 0xFFFF - (2^24/Plaback Freq in hz) to the register. This sets the start value such that the timer will
overflow precisely when the next sound sample is needed, and cause the DMA to activate. When using interrupts,
set the start value of these to 0, but use <A HREF="#REG_TM0CNT">REG_TMXCNT</A> to change the update frequency
to 1024, thus causing an interrupt rate of 16.384khz.<BR>
<BR>
<B><BR>
Address: 0x4000102 - <A NAME="REG_TM0CNT"></A>REG_TM0CNT (Timer 0 Control)<BR>
Address: 0x4000106 - <A NAME="REG_TM1CNT"></A>REG_TM1CNT (Timer 1 Control)<BR>
Address: 0x400010A - <A NAME="REG_TM2CNT"></A>REG_TM2CNT (Timer 2 Control)<BR>
Address: 0x400010E - <A NAME="REG_TM3CNT"></A>REG_TM3CNT (Timer 3 Control)</B></P>
<PRE><FONT COLOR="#FF0000">                             *</FONT>
F E D C  B A 9 8  7 6 5 4  3 2 1 0 
<FONT COLOR="#BBBBBB">X X X X  X X X X</FONT><FONT COLOR="#008800">  E </FONT><FONT COLOR="#0099FF">I</FONT> <FONT
COLOR="#BBBBBB">X X  X</FONT> <FONT COLOR="#9900CC">C </FONT><FONT COLOR="#FF0099">F F</FONT></PRE>
<PRE>0-1 <FONT COLOR="#FF0099">(F)</FONT> = Frequency at which the timer updates.

          00: Default frequency (full) - 16.78MHz (~17mlns ticks per second)
          01: Every 64 clock pulses - ~262187.5KHz
          10: Every 256 clock pulses - ~65546.875KHz
          11: Every 1024 clock pulses - ~16386.71875KHz

2   <FONT COLOR="#9900CC">(C)</FONT> = Cascade (<FONT COLOR="#DD0000">*</FONT> Unused on TM0) - When this bit is set, the frequency of this
          timer is ignored. Instead the timer increments when the timer below it
          overflows. For example, if timer 1 is set to cascade, it will increment
          whenever timer 0's value goes from 0xFFFF to 0x0000.
6   <FONT COLOR="#0099FF">(I)</FONT> = Generate an interrupt on overflow
7 <FONT COLOR="#008800">  (E)</FONT> = Enable the timer.</PRE>
<H3><BR>

<HR ALIGN="CENTER">
<BR>
Addresses 0x4000120 - 0x400012A - <A NAME="Serial Communication Registers"></A>Serial Communication Registers)
(Unimplemented in CowBite)</H3>
<P>Note: All of the serial comm information originates from <A HREF="http://members.truepath.com/AndrewMay/GBA.html">Andrew
May's description</A> of the GBA linker hardware, which in turn was compiled from various other sources on the
web. My thanks to ePAc for discovering his site and putting the information into a format consistent with the rest
of this spec. If anybody else has information to add to this, don't hesitate to mail me.<B> <BR>
<BR>
Address: 0x4000120 - <A NAME="REG_SCD0"></A>REG_SCD0 (Master/Slave 0 destination reg) (Read Only)<BR>
Address: 0x4000122 - <A NAME="REG_SCD1 "></A>REG_SCD1 (Slave 1 destination reg) (Read Only)<BR>
Address: 0x4000124 - <A NAME="REG_SCD2"></A>REG_SCD2 (Slave 2 destination reg) (Read Only)<BR>
Address: 0x4000126 - <A NAME="REG_SCD3"></A>REG_SCD3</B> <B>(Slave 3 destination reg) (Read Only)</B></P>
<PRE><FONT COLOR="#FF0000">
R R R R  R R R R  R R R R  R R R R</FONT>
F E D C  B A 9 8  7 6 5 4  3 2 1 0 
<FONT COLOR="#FF0099">D D D D  D D D D  D D D D  D D D D</FONT>
</PRE>
<PRE>0-F <FONT COLOR="#FF0099">(D)</FONT> = The data received.</PRE>
<P>- SCD0 contains the data sent by the master (also called slave 0)<BR>
- SCD1 contains the data sent by the first slave (slave1)<BR>
- SCD2 contains the data sent by the second slave (slave2)<BR>
- SCD3 contains the data sent by the last slave (slave3)<BR>
<BR>
<B><BR>
Address: 0x4000128 - <A NAME="REG_SCCNT_L"></A>REG_SCCNT_L (Serial Communication channel control register)</B></P>
<PRE><FONT COLOR="#FF0000">                    R               </FONT>   
F E D C  B A 9 8  7 6 5 4  3 2 1 0
<FONT COLOR="#BBBBBB">X </FONT><FONT COLOR="#9900CC">I</FONT> <FONT COLOR="#FF0099">M M</FONT> <FONT COLOR="#BBBBBB"> X X X X </FONT><FONT
COLOR="#FF3300"> S</FONT> <FONT COLOR="#008800">E</FONT> <FONT COLOR="#0099FF">D D</FONT> <FONT COLOR="#9900CC"> L L</FONT> <FONT
COLOR="#FF0099">B B</FONT></PRE>
<PRE>0-1 <FONT COLOR="#FF0099">(B)</FONT> = Baud rate [00=9600,01=38400,10=57600,11=115200]
2-3 <FONT COLOR="#9900CC">(L)</FONT> = SD(bit3) and SI(bit2) line direct access
4-5 <FONT COLOR="#0099FF">(D)</FONT> = ID of GBA [00=master,01=slave1,10=slave2,11=slave3]
6   <FONT COLOR="#008800">(E)</FONT> = Error (1 on error)
7 <FONT COLOR="#FF3300">  (S)</FONT> = Start Transfer (1 triggers the start on the MASTER ONLY)
C-D <FONT COLOR="#FF0099">(M)</FONT> = Comm Mode [8bit=00,32bit=01,Multilink=10,UART=11]
E <FONT COLOR="#9900CC">  (I)</FONT> = Enable Comm Interupt</PRE>
<P><BR>
Using the link port and a link cable, the GBA can transmit serial data in one of four modes: 8 bit, 32 bit, Multilink,
and UART. At the moment I only have info on the multilink mode. <A HREF="mailto:SorcererXIII@yahoo.com">Mail me</A>
if you know more about the other modes.<BR>
<BR>
<A NAME="Multilink Mode"></A><B>Multilink Mode</B><BR>
To transfer data in this mode, you must coordinate the actions of all the GBAs which are linked together. Each
GBA slave must place the data they wish transfered in <A HREF="#REG_SCCNT_H">REG_SCCNT_H</A>. Then the Master/Slave
0 initiates the transfer by setting bit 7 of REG_SCCNT_L. This causes the hardware to transfer the data and, as
I understand, it will magically appear in the destination registers of each slave, according to the following:<BR>
<BR>
<A HREF="#REG_SCCNT_H">REG_SCCNT_H</A> from GBA with id 00 goes into <A HREF="#REG_SCD0">REG_SCD0</A> on each GBA<BR>
<A HREF="#REG_SCCNT_H">REG_SCCNT_H</A> from GBA with id 01 goes into <A HREF="#REG_SCD0">REG_SCD1</A> on each GBA<BR>
<A HREF="#REG_SCCNT_H">REG_SCCNT_H</A> from GBA with id 10 goes into <A HREF="#REG_SCD0">REG_SCD2</A> on each GBA<BR>
<A HREF="#REG_SCCNT_H">REG_SCCNT_H</A> from GBA with id 11 goes into <A HREF="#REG_SCD0">REG_SCD3</A> on each GBA<BR>
<BR>
Thus each GBA in the chain has a duplicate of the data. <BR>
<BR>
It is unclear to me how each GBA knows what ID it is; perhaps this value is automatically set when the link cable
is attached? ePAc has commented that the master is the GBA in the set that has the purple connector connected to
its ext port. So if you have a GBA that want to be a MBserver for a set of clients, then you need to put the cart
in the one with the purple connector..<BR>
<BR>
Note from me: I have a suspicion that some of these bits are write-only. Please let me know if you find out more.<BR>
<B><BR>
<BR>
Address: 0x400012A - <A NAME="REG_SCCNT_H"></A>REG_SCCNT_H (Serial Communication Source Register)</B></P>
<PRE>F E D C  B A 9 8  7 6 5 4  3 2 1 0 
<FONT COLOR="#FF33CC">S S S S  S S S S  S S S S  S S S S</FONT></PRE>
<PRE>0-F <FONT COLOR="#FF0099">(S)</FONT> = The data to be sent over the link cable.</PRE>
<H3><BR>

<HR ALIGN="CENTER">
<BR>
Addresses 0x4000130 - 0x4000132 - <A NAME="Keypad input and control registe"></A>Keypad Input and Control Registers</H3>
<P><BR>
<B>Address: 0x4000130 - <A NAME="REG_KEY"></A>REG_KEY (The input register)(Read Only)</B></P>
<PRE><FONT COLOR="#FF0000">             R R  R R R R  R R R R</FONT>
F E D C  B A 9 8  7 6 5 4  3 2 1 0 
<FONT COLOR="#BBBBBB">X X X X  X X</FONT> <FONT COLOR="#FF3300">J </FONT><FONT COLOR="#008800">I</FONT><FONT COLOR="#0099FF">  D</FONT> <FONT
COLOR="#9900CC">U</FONT> <FONT COLOR="#FF0099">L</FONT> <FONT COLOR="#FF3300">R</FONT> <FONT COLOR="#008800"> S</FONT><FONT
COLOR="#0099FF"> E</FONT> <FONT COLOR="#9900CC">B</FONT> <FONT COLOR="#FF0099">A</FONT> </PRE>
<PRE>0 <FONT COLOR="#FF0099">(A)</FONT> = A button 
1 <FONT COLOR="#9900CC">(B)</FONT> = B button 
2 <FONT COLOR="#0099FF">(E)</FONT> = Select button 
3 <FONT COLOR="#008800">(S)</FONT> = Start button 
4 <FONT COLOR="#FF3300">(R)</FONT> = D-pad Right 
5 <FONT COLOR="#FF0099">(L)</FONT> = D-pad Left 
6 <FONT COLOR="#9900CC">(U)</FONT> = D-pad Up 
7 <FONT COLOR="#0099FF">(D)</FONT> = D-pad Down 
8 <FONT COLOR="#008800">(I)</FONT> = Right shoulder button 
9 <FONT COLOR="#FF3300">(J)</FONT> = Left shoulder button </PRE>
<P><BR>
This register stores the state of the GBA's buttons. Each of the inputs is active low. This means that a '0' bit
indicates that the key is pressed, while a '1' bit indicates that the key is not pressed. In general a game which
samples these (rather than using interrupts) should do so at least once every refresh (60hz), or more in the case
of fast action fighting games (like Street Fighter).<BR>
<BR>
<B>Address: 0x4000132 - <A NAME="REG_KEYCNT"></A>REG_P1CNT (Key Control Register - As yet unimplemented in CowBite)</B></P>
<PRE>    
F E D C  B A 9 8  7 6 5 4  3 2 1 0 
<FONT COLOR="#9900CC">T</FONT> <FONT COLOR="#FF0099">K</FONT> <FONT COLOR="#BBBBBB">X X  X X </FONT><FONT COLOR="#FF3300">J </FONT><FONT
COLOR="#008800">I</FONT><FONT COLOR="#0099FF">  D</FONT> <FONT COLOR="#9900CC">U</FONT> <FONT COLOR="#FF0099">L</FONT> <FONT
COLOR="#FF3300">R</FONT> <FONT COLOR="#008800"> S</FONT><FONT COLOR="#0099FF"> E</FONT> <FONT COLOR="#9900CC">B</FONT> <FONT
COLOR="#FF0099">A</FONT> 

</PRE>
<PRE>0 <FONT COLOR="#FF0099">(A)</FONT> = A button 
1 <FONT COLOR="#9900CC">(B)</FONT> = B button 
2 <FONT COLOR="#0099FF">(E)</FONT> = Select button 
3 <FONT COLOR="#008800">(S)</FONT> = Start button 
4 <FONT COLOR="#FF3300">(R)</FONT> = D-pad Right 
5 <FONT COLOR="#FF0099">(L)</FONT> = D-pad Left 
6 <FONT COLOR="#9900CC">(U)</FONT> = D-pad Up 
7 <FONT COLOR="#0099FF">(D)</FONT> = D-pad Down 
8 <FONT COLOR="#008800">(I)</FONT> = Right shoulder button 
9 <FONT COLOR="#FF3300">(J)</FONT> = Left shoulder button 
E <FONT COLOR="#FF0099">(K)</FONT> = generate interrupt on keypress
F <FONT COLOR="#9900CC">(T)</FONT> = interrupt &quot;type&quot;
        0: &quot;OR&quot; operation -- interrupt will be generated if _any_ of specified
           keys (bits 0-9) is pressed
        1: &quot;AND&quot; operation, interrupt will be generated if _all_ specified keys
           are pressed at the same time.</PRE>
<P>Use this register to set which keypresses generate interrupts. The appropriate bits must also be set in <A HREF="#REG_IE">REG_IE</A>
and <A HREF="#REG_IME">REG_IME</A>.
<H4><BR>

<HR ALIGN="CENTER">
<BR>
Address: 0x4000134 - <A NAME="REG_R"></A>REG_R</H4>
<PRE>    <FONT COLOR="#FF0000">R R  R R R                 R R</FONT>    
F E D C  B A 9 8  7 6 5 4  3 2 1 0
</PRE>
<P>This register appears to give direct access to the different lines of the link port. If you happen to have more
information about which bit corresponds to which line, by all means <A HREF="mailto:SorcererXIII@yahoo.com">mail
me</A> about it so I can update the doc.<BR>
<BR>
Also, I used the name listed in Eloist's <A HREF="gba.h">gba.h</A>. I don't think it is very descriptive. If anyone
has seen a better name for this register, let me know and I will change it. Otherwise I will probably change it
to something like &quot;REG_SCLINES&quot; or &quot;REG_SCPIN&quot;.
<H3>
<HR ALIGN="CENTER">
<BR>
<BR>
Addresses 0x4000200 - 0x4000208 - <A NAME="Interrupt Registers"></A>Interrupt Registers</H3>
<P><B><BR>
Address: 0x4000200 - <A NAME="REG_IE"></A>REG_IE (Interrupt Enable Register)</B></P>
<PRE>F E D C  B A 9 8  7 6 5 4  3 2 1 0 
<FONT COLOR="#BBBBBB">X X</FONT> <FONT COLOR="#008800">T </FONT><FONT COLOR="#0099FF">Y  </FONT><FONT COLOR="#9900CC">G </FONT><FONT
COLOR="#FF0099">F </FONT><FONT COLOR="#FF3300">E </FONT><FONT COLOR="#008800">D  </FONT><FONT COLOR="#0099FF">S </FONT><FONT
COLOR="#9900CC">L </FONT><FONT COLOR="#FF0099">K </FONT><FONT COLOR="#FF3300">J </FONT><FONT COLOR="#008800"> I </FONT><FONT
COLOR="#0099FF">C </FONT><FONT COLOR="#9900CC">H </FONT><FONT COLOR="#FF0099">V</FONT>
</PRE>
<PRE>0 <FONT COLOR="#FF0099">(V)</FONT> = VBlank Interrupt 
1 <FONT COLOR="#9900CC">(H)</FONT> = HBlank Interrupt 
2 <FONT COLOR="#0099FF">(C)</FONT> = VCount Interrupt 
3 <FONT COLOR="#008800">(I)</FONT> = Timer 0 Interrupt 
4 <FONT COLOR="#FF3300">(J)</FONT> = Timer 1 Interrupt 
5 <FONT COLOR="#FF0099">(K)</FONT> = Timer 2 Interrupt 
6 <FONT COLOR="#9900CC">(L)</FONT> = Timer 3 Interrupt 
7 <FONT COLOR="#0099FF">(S)</FONT> = Serial Communication Interrupt 
8 <FONT COLOR="#008800">(D)</FONT> = DMA0 Interrupt 
9 <FONT COLOR="#FF3300">(E)</FONT> = DMA1 Interrupt 
A <FONT COLOR="#FF0099">(F)</FONT> = DMA2 Interrupt 
B <FONT COLOR="#9900CC">(G)</FONT> = DMA3 Interrupt 
C <FONT COLOR="#0099FF">(Y)</FONT> = Key Interrupt 
D <FONT COLOR="#008800">(T)</FONT> = Cassette Interrupt </PRE>
<P><BR>
Use this register to mask out which interrupts are enabled or disabled. <BR>
<BR>
<B>Address: 0x4000202 - <A NAME="REG_IF"></A>REG_IF (Interrupt Flags Regster)</B></P>
<PRE>F E D C  B A 9 8  7 6 5 4  3 2 1 0 
<FONT COLOR="#BBBBBB">X X</FONT> <FONT COLOR="#008800">T </FONT><FONT COLOR="#0099FF">Y  </FONT><FONT COLOR="#9900CC">G </FONT><FONT
COLOR="#FF0099">F </FONT><FONT COLOR="#FF3300">E </FONT><FONT COLOR="#008800">D  </FONT><FONT COLOR="#0099FF">S </FONT><FONT
COLOR="#9900CC">L </FONT><FONT COLOR="#FF0099">K </FONT><FONT COLOR="#FF3300">J </FONT><FONT COLOR="#008800"> I </FONT><FONT
COLOR="#0099FF">C </FONT><FONT COLOR="#9900CC">H </FONT><FONT COLOR="#FF0099">V</FONT>
</PRE>
<PRE>0 <FONT COLOR="#FF0099">(V)</FONT> = VBlank Interrupt 
1 <FONT COLOR="#9900CC">(H)</FONT> = HBlank Interrupt 
2 <FONT COLOR="#0099FF">(C)</FONT> = VCount Interrupt 
3 <FONT COLOR="#008800">(I)</FONT> = Timer 0 Interrupt 
4 <FONT COLOR="#FF3300">(J)</FONT> = Timer 1 Interrupt 
5 <FONT COLOR="#FF0099">(K)</FONT> = Timer 2 Interrupt 
6 <FONT COLOR="#9900CC">(L)</FONT> = Timer 3 Interrupt 
7 <FONT COLOR="#0099FF">(S)</FONT> = Serial Communication Interrupt 
8 <FONT COLOR="#008800">(D)</FONT> = DMA0 Interrupt 
9 <FONT COLOR="#FF3300">(E)</FONT> = DMA1 Interrupt 
A <FONT COLOR="#FF0099">(F)</FONT> = DMA2 Interrupt 
B <FONT COLOR="#9900CC">(G)</FONT> = DMA3 Interrupt 
C <FONT COLOR="#0099FF">(Y)</FONT> = Key Interrupt 
D <FONT COLOR="#008800">(T)</FONT> = Cassette Interrupt </PRE>
<P>This register will determine which interrupt is currently being serviced. When your interrupt service routine
get scalled, check these flags to determine what called it. In order to keep yourself from servicing the wrong
interrupt at a later time, you should reset the flags to 0 by writing a 1 to them. <BR>
<BR>
<BR>
<B>Address: 0x4000204 - <A NAME="REG_WS_CR"></A>REG_WSCNT (Wait State Control)</B></P>
<PRE><FONT COLOR="#FF0000">R   </FONT>
F E D C  B A 9 8  7 6 5 4  3 2 1 0 
<FONT COLOR="#FF3300">G</FONT> <FONT COLOR="#008800">P</FONT> <FONT COLOR="#BBBBBB">X</FONT> <FONT COLOR="#0099FF">C  C</FONT> <FONT
COLOR="#9900CC">N</FONT><FONT COLOR="#008800"> </FONT><FONT COLOR="#FF0099">M M</FONT><FONT COLOR="#CC0099"> </FONT><FONT
COLOR="#0099FF"> </FONT><FONT COLOR="#FF3300">L</FONT><FONT COLOR="#0099FF"> </FONT><FONT COLOR="#008800">K K</FONT> <FONT
COLOR="#0099FF">J</FONT><FONT COLOR="#9900CC">  I I</FONT> <FONT COLOR="#FF0099">S S</FONT></PRE>
<PRE>0-1 <FONT COLOR="#FF0099">(S)</FONT> = <A HREF="#CART RAM">SRAM</A> wait state
          00:  4 cycles          01:  3 cycles
          10:  2 cycles          11:  8 cycles
2-3 <FONT COLOR="#9900CC">(I)</FONT> = <A HREF="#GAME PAK ROM">Bank 0x08000000</A> initial wait state
          00: 4 cycles           01: 3 cycles
          10: 2 cycles           11: 8 cycles
4   <FONT COLOR="#0099FF">(J)</FONT> = Bank 0x08000000 subsequent wait state
          0: _2_ cycles  1: 1 cycle
5-6 <FONT COLOR="#008800">(K)</FONT> = <A HREF="#ROM IMAGE 1">Bank 0x0A000000</A> initial wait state
          00: 4 cycles           01: 3 cycles
          10: 2 cycles           11: 8 cycles
7   <FONT COLOR="#FF3300">(L)</FONT> = Bank 0x0A000000 subsequent wait state
          0: _4_ cycles  1: 1 cycle
8-9 <FONT COLOR="#FF0099">(M)</FONT> = <A HREF="#ROM IMAGE 2">Bank 0x0C000000</A> initial wait state
          00: 4 cycles           01: 3 cycles
          10: 2 cycles           11: 8 cycles
A   <FONT COLOR="#9900CC">(N)</FONT> = Bank 0x0C000000 subsequent wait state
          0: _8_ cycles          1: 1 cycle
B-C <FONT COLOR="#0099FF">(C)</FONT> = Cart clock.  Don't touch.
          00:  Terminal output clock fixed lo
          01:  4 Mhz
          10:  8 Mhz
          11:  16 Mhz
E   <FONT COLOR="#008800">(P)</FONT> = Prefetch.  The GBA's 8-word-by-16-bit prefetch buffer makes
          subsequent ROM reads faster in code that accesses both ROM
          and RAM.
          0: Disable (and save battery power)
          1: Enable
F   <FONT COLOR="#FF3300">(G)</FONT> = Game Pak type
          0: AGB multiplexed bus
          1: DMG/CGB bus)
</PRE>
<P>Use this register to control wait state settings and the prefetch buffer for ROM and SRAM. Thanks to <A HREF="http://pineight.com/contact/">Damian
Yerrick</A> for contributing this info, and for pointing me to some relevant reading material.<BR>
<BR>
<BR>
<B><BR>
Address: 0x4000208 - <A NAME="REG_IME"></A>REG_IME (Interrupt Master Enable)</B></P>
<PRE>F E D C  B A 9 8  7 6 5 4  3 2 1 0 
<FONT COLOR="#BBBBBB">X X X X  X X X X  X X X X  X X X</FONT> <FONT COLOR="#FF0099">M</FONT> 
</PRE>
<PRE>0 <FONT COLOR="#FF0099">(M)</FONT> = Master interrupt enable. When off, all interrupts are disabled.  This
        must be on for the interrupt bits in <A HREF="#REG_IE">REG_IE</A> to have any effect.</PRE>
<P><BR>
<BR>

<HR ALIGN="CENTER">
<BR>
<B>Address: 0x4000300 - <A NAME="REG_PAUSE"></A>REG_PAUSE</B></P>
<PRE><FONT COLOR="#FF0000">? ? ? ?  ? ? ? ?  ? ? ? ?  ? ? ? ?</FONT>
F E D C  B A 9 8  7 6 5 4  3 2 1 0 
<FONT COLOR="#9900CC">P </FONT><FONT COLOR="#FF0099">M </FONT><FONT COLOR="#BBBBBB">X X  X X X X  X X X X  X X X X</FONT></PRE>
<PRE>F <FONT COLOR="#FF0099">(M)</FONT> = Mode
E <FONT COLOR="#9933FF">(P)</FONT> = Power down
</PRE>
<P><BR>
I've written down the function of this as it appears in <A HREF="http://www.bottledlight.com/docs/sdk.html">Mappy's
SDK</A>. However, I can't say how it works. Writing values to bits 14 and 15 seems to have no effect. This register
shows up as 0x0001 when read. As always, send me mail if you have more info on this.
<H2><BR>

<HR ALIGN="CENTER">
<BR>
11. <A NAME="Miscellaneous"></A>Miscellaneous/Weirdness</H2>
<P>This is a new section devoted any interesting little tidbits that don't quite fit in anywhere else. I'm starting
it off with . . .
<H3>Unknown Registers</H3>
<P>These are registers that I don't know the function of. While most aren't even readable, certain ones seem to
be writeable. I have an idea of what some of them are based on the headers included with many open source demos,
but as to their specific function, I have no idea. Let me know if you find out what purpose they serve, if any,
and I will put your notes here (and of course give credit).</P>
<PRE>0x002:         REG_DISPCNT_H - Writing to bit 0 will cause (horizontally)
               adjacent pairs of pixels to have their green component
               swapped. What good is this for?  Anybody know?

0x04E:         REG_MOSAIC_H - Unreadable (gobbledygook)
0x056 - 0x05E:	Unreadable (gobbledygook)
0x066:         REG_SOUND1CNT_X (high 16 bits) Unreadable (0x0000)
0x06A:         REG_SOUND2CNT_L (high 16 bits) Unreadable (0x0000)
0x06E:         REG_SOUND2CNT_H (high 16 bits) Unreadable (0x0000)
0x076:         REG_SOUND3CNT_X (high 16 bits) Unreadable (0x0000)
0x07A:         REG_SOUND4CNT_L (high 16 bits) Unreadable (0x0000)
0x07E:         REG_SOUND4CNT_L (high 16 bits) Unreadable (0x0000)
0x086:         REG_SOUNDCNT_X (high 16 bits) Unreadable (0x0000)
0x08A:         REG_SOUNDBIAS (high 16 bits) Unreadable (0x0000)
0x08C:         Unreadable (gobbledygook)
0x08E:         Unreadable (gobbledygook)
0x0A8 - 0xAE:  Unreadable (gobbledygook)
0x0E0 - 0x0FE: Unreadable (gobbledygook)
0x110 - 0x11E: Unreadable (gobbledygook)
0x12C:         Unreadable (gobbledygook)
0x12E:         Unreadable (gobbledygook)
0x136:         REG_R (high 16 bits) Unreadable (0x0000)
0x138 - 13E:   Unreadable (gobbledygook)

0x140:	       REG_HS_CTRL - Seems to have the following properties:
               <FONT COLOR="#FF0000">R R R R  R R R R  R   R R  R R R R</FONT>
               F E D C  B A 9 8  7 6 5 4  3 2 1 0

0x142:         Unreadable (0x0000)
0x144-14E:     Unreadable (gobbledygook)
0x150:         REG_JOYRE_L - Unreadable (0x0000)
0x152:         REG_JOYRE_H - Unreadable (0x0000)
0x154:         REG_JOYTR_L - Unreadable (0x0000)
0x156:         REG_JOYTR_H - Unreadable (0x0000)
0x158:         JOYSTAT_L - defaults to 0x8.  
               Seems to have the following properties: 
<FONT COLOR="#FF0000">               R R R R  R R R R  R R        R R R</FONT>
               F E D C  B A 9 8  7 6 5 4  3 2 1 0

0x15A:         JOYSTAT_H - Unreadable (0x0000)
0x15C - 0x1FE: Unreadable (gobbledygook)
0x206:         REG_WSCNT (high 16 bits) Unreadable (0x0000)
0x20A:         REG_IME (high 16 bits) Unreadable (0x0000)
0x20C - 0x2FE: Unreadable (gobbledygook)
0x302:         REG_PAUSE (high 16 bits) Unreadable (0x0000)
0x304 - 0x3FE: Unreadable (gobbledygook)
0x800:         Seems to have the following properties: 
			
               F E D C  B A 9 8  7 6 5 4  3 2 1 0
               <FONT COLOR="#BBBBBB">X X X X  X X X X  X X</FONT> <FONT COLOR="#FF3300">M</FONT> <FONT COLOR="#BBBBBB">X</FONT>  <FONT
COLOR="#008800">L</FONT> <FONT COLOR="#0099FF">K</FONT> <FONT COLOR="#9900CC">J</FONT> <FONT COLOR="#FF0099">I
				
               </FONT>0 <FONT COLOR="#FF0099">(I)</FONT> = When set, this sets the top-left tile number to 0x82
<FONT COLOR="#FF0099">               </FONT>1 <FONT COLOR="#9900CC">(J)</FONT> = Unknown.
<FONT COLOR="#FF0099">               </FONT>2 <FONT COLOR="#0099FF">(K)</FONT> = Unknown.
<FONT COLOR="#FF0099">               </FONT>3 <FONT COLOR="#008800">(L)</FONT> = Unkown.
<FONT COLOR="#FF0099">               </FONT>5 <FONT COLOR="#FF3300">(M)</FONT> = When unset this disallows VRAM changes (but can be used
<FONT COLOR="#FF0099">                       </FONT>simulteneously with bit 0).  It is set by default.

<FONT COLOR="#FF0099">               </FONT>What little we know about this register comes from gbcft's 
               experimentation a ways back, and he's not entirely sure about
               even this.  Anybody who knows about it can feel free to <A HREF="mailto:SorcererXIII@yahoo.com">email
</A>               me with more info. <FONT COLOR="#FF0099">

               </FONT>This register (the whole 32 bit word) is also mirrored at
<FONT COLOR="#FF0099">               </FONT>intervals of 0x10000 bytes in IORAM (it is the only IORAM
<FONT COLOR="#FF0099">               </FONT>register that is mirrored in in this way).  

0x802:         Read only (reads as 0x0d00).
</PRE>
<P>I have noted that some of these registers always read as a certain repeating gobbledygook value no matter what
is written to them (I take this to be of the same origin as the gobbledygook that comes from reading BIOS -- see
<A HREF="http://www.devrs.com/gba">Jeff Frohwein's</A> GBA FAQ), but some always read 0. For the most part these
seem to be the &quot;high&quot; 16 bits of registers we already know the function of (thanks gbcft for pointing
out what probably should have been obvious to me). Others are registers that probably do something, but I just
don't know what. They may read as something other than 0 if the conditions are right.<BR>
<BR>
<B>Possibilities:</B><BR>
The following are some suggested possiblities for what the unkown registers could be (thanks goes out to Kay for
this), based on what Nintendo has included in previous hardware:<BR>
<BR>
SPR_TIME_OVER bit: sprite blit time out register (1 bit). This bit is set when sprite processing overloads during
HDraw<BR>
SPR_RANGE_OVER bit: displayed objects number (regardless of the size) becomes or is greater than maximum GFX ASIC
is able to process<BR>
xxxx_VER_NUMBER reg: regsiter containing the xxxx IC version number (usually bit 0 to 3 if made by Nintendo)<BR>
<BR>
- Like all Nintendo hardware designs, the GBA may have one or more 8/16 bit in/out parallel data ports mapped at
the bottom of I/O addresses.<BR>

<H2>12. <A NAME="Links"></A>Links</H2>
<P>The following are links to other documents which should prove useful to GBA developers:<BR>
<BR>
<A HREF="http://www.gbadev.org">www.gbadev.org</A> (A great resource for GBA developers)<BR>
<A HREF="http://www.devrs.com/gba/">Devrs.com GBA Site</A> (Another great resource, maintained by Jeff Frohwein)<BR>
<A HREF="http://www.devrs.com/gba/files/gbadevfaqs.php">Jeff Frohwein's GBA Dev FAQ</A><BR>
<A HREF="http://216.167.73.47/~dovoto/">The Pern Project</A> (Tutorials for GBA development)<BR>
<A HREF="http://www.bottledlight.com/docs/sdk.html">Mappy SDK</A> (A document similar to this one but for Joat's
<A HREF="http://www.bottledlight.com/">Mappy</A> emulator)<BR>
<A HREF="http://www.bottledlight.com/">Mappy</A> (A great emulator for developers)<BR>
<A HREF="http://www.arm.com/arm/TRMs?OpenDocument">ARM's Technical Reference Manuals</A> (Docs that you should
have around if you want to understand the ARM processor)<BR>
<A HREF="http://belogic.com/gba/">The Audio Advance</A> (A great site by Uze explaining the GBA's sound system)
<BR>
<A HREF="http://members.truepath.com/AndrewMay/GBA.html">Andrew May's site</A> (Technical info on the GBA link
port)<BR>
<A HREF="http://cowbite.emuunlim.com/index.php">CowBite</A> (The emulator I've been writing off and on. Make sure
you check it out and <A HREF="mailto:SorcererXIII@yahoo.com">give me feedback</A>!)
<H2><BR>
13. <A NAME="Thanks"></A>Thanks</H2>
<P><BR>
<B>The following are individuals who contributed info or corrections to this document. Thanks guys!<BR>
</B><BR>
Agent Q (Wrote the original spec, version 1.0)<BR>
Uze (All of the sound register info comes directly from his <A HREF="http://belogic.com/gba/">Audio Advance</A>
site)<BR>
gbcft (LOTS of info on interrupts, windowing, memory mirrors, the &quot;Unkown Registers&quot; section, as well
as many corrections, info, and suggestions)<A HREF="http://pineight.com/contact/"><BR>
Damian Yerrick</A> (Contributed the WSCOUNT register)<BR>
Kay (Contributed memory port sizes and wait states, DMA cycle timings, and various advice, testing, and expertise
regarding the GBA and older console systems)<BR>
Markus (Actually I asked him for help, and he kindly supplied me with what I needed to understand LZSS compression)<BR>
ePac (Gave me links to serial info and did a nice writeup about it in the gbadev group)<BR>
Costis (A variety of new info/corrections)<BR>
Grauw (Info on forced blanking, hblank lenghths, and on the BIOS wait function.)<BR>
Max<BR>
Otaku<BR>
Ped (Pointed out errors in the memory ranges, DISPCNT bit 5, and a bad typo regarding rotates/scale backgrounds).<BR>
Yarpen (Almost all the information on the timer registers and the keyboard control register. Thanks!)<BR>
<BR>
<B><BR>
General Thanks</B><BR>
<BR>
All those GBA demo authors. You rock!<BR>
Every other emu author<BR>
<A HREF="http://www.gbadev.org">www.gbadev.org</A><BR>
The gbadev list on yahoo<BR>
SimonB and all the others who run/moderate the above sites<BR>
Dovoto and the <A HREF="http://216.167.73.47/~dovoto/">PERN Project</A><BR>
Jeff Frohwein and his <A HREF="http://www.devrs.com/gba">Devrs.com</A> site<BR>
Nocturn and his tutorials<BR>
Uze from <A HREF="http://belogic.com/gba/">BeLogic</A> for all the great information on the GBA's sound!<BR>
Andrew May for his site on GBA serial data<BR>
Nintendo <BR>
<BR>
If I've forgotten to list your name or an important resource in this section, <A HREF="SorcererXIII@yahoo.com">let
me know</A>.</P>
<P ALIGN="CENTER"><FONT SIZE="2">This document and its author are in no way associated with, endorsed or supported
by<BR>
Nintendo. GBA and Game Boy Advance are registered trademarks of Nintendo.<BR>
The CowBite emulator itself is copyright 2002 Thomas Happ</FONT>

</BODY>

</HTML>